React/Redux와 요소를 결합하여 사용
개요
redux의 store
의 내용을 사용하여 <canvas>
요소를 그리고 싶었는데 보통으로 해도 잘되지 않았으므로 해결 방법을 메모해 둡니다. 문제의 원인은 <canvas>
의 내용을 괴롭히는 경우는 DOM을 직접 조작할 필요가 있으므로, 근본적으로 react와 궁합이 나쁜 것입니다. 일단 적당하게 검색하고 있으면 나왔다.
결론
<canvas>
의 묘화는 최초회만 react로부터 실시해, 그 후에는 react로부터 직접은 만지지 않도록 한다. 이를 위해 <canvas>
요소를 포함하는 React.Component
<canvas>
의 묘화는 최초회만 react로부터 실시해, 그 후에는 react로부터 직접은 만지지 않도록 한다. 이를 위해 <canvas>
요소를 포함하는 React.Component
<canvas>
요소를 ref
로 설정하고 componentDidMount()
에서 context
의 설정과 첫 그리기를, shouldComponentUpdate()
에서 ref
로부터 직접 DOM을 조작해 묘화 내용의 갱신을 실시해, false
데모
간단한 예로, 양식에 입력한 텍스트를 <canvas>
에 이미지로 그려야 합니다.
react와 d3.js를 결합하는 예
코드
코드는 github ( ) 에 있습니다. 이하, 간단히 설명합니다.
먼저 다음과 같이 index.js
에서 reducer
와 store
를 정의해 둡니다. state
의 구조는 매우 간단하며 양식에 입력된 텍스트(= <canvas>
에 그리려는 텍스트)의 내용만 관리합니다.
index.jsimport React from 'react'
import ReactDOM from 'react-dom'
import { createStore } from 'redux'
import { Form, Canvas } from './components'
const initialState = {text: ''}
const reducer = (state = initialState, action) => {
switch (action.type) {
case 'CHANGE_TEXT':
return {
...state,
text: action.text
}
default:
return state
}
}
const store = createStore(reducer)
const render = () => {
ReactDOM.render(
<div>
<Form store={store}/>
<Canvas store={store}/>
</div>,
document.getElementById('root')
)
}
store.subscribe(() => render())
render()
이하, render()
내부에서 사용하고 있는 <Form />
와 <Canvas />
를 정의해 갑니다. 우선 <Form />
에 대해서는 보통으로 쓰면 됩니다.
components.jsimport React, { Component } from 'react'
export const Form = ({ store }) => {
const { text } = store.getState()
return (
<div>
<input
value={text}
onChange={e => store.dispatch({
type: 'CHANGE_TEXT',
text: e.target.value
})}
/>
</div>
)
}
보통입니다. <input>
의 value
를 store
다음으로, 문제가 되는 dispatch
요소를 포함한 <canvas>
컴퍼넌트입니다.
components.js에 추가const canvasWidth = 300
const canvasHeight = 50
export class Canvas extends Component {
componentDidMount() {
this.ctx = this.refs.canvas.getContext('2d')
this.ctx.textAlign = 'center'
this.ctx.font = '24px sans-serif'
const { text } = this.props.store.getState()
this.ctx.fillText(text, canvasWidth / 2, canvasHeight / 2)
}
shouldComponentUpdate() {
const { text } = this.props.store.getState()
this.ctx.clearRect(0, 0, canvasWidth, canvasHeight)
this.ctx.fillText(text, canvasWidth / 2, canvasHeight / 2)
return false
}
render() {
return (
<div>
<canvas ref="canvas" width={canvasWidth} height={canvasHeight} />
</div>
)
}
}
이런 식으로, <Canvas />
내부에서 기본적인 설정과 묘화를 실시해, componentDidMount()
내부에서 shouldComponentUpdate()
의 상태를 store
에 반영하는 것으로 잘 움직였습니다. 이 방법이라면 redux <canvas>
가 업데이트 될 때마다 store
가 불려 그 안에서 직접 DOM을 조작하고 그 후 shouldComponentUpdate()
를 반환하기 때문에 react는 더 이상 false
를 변경하지 않는다는 것이 가능합니다.
Reference
이 문제에 관하여(React/Redux와 요소를 결합하여 사용), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다
https://qiita.com/maiyama18/items/2524b3b898c802a6b97e
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)
import React from 'react'
import ReactDOM from 'react-dom'
import { createStore } from 'redux'
import { Form, Canvas } from './components'
const initialState = {text: ''}
const reducer = (state = initialState, action) => {
switch (action.type) {
case 'CHANGE_TEXT':
return {
...state,
text: action.text
}
default:
return state
}
}
const store = createStore(reducer)
const render = () => {
ReactDOM.render(
<div>
<Form store={store}/>
<Canvas store={store}/>
</div>,
document.getElementById('root')
)
}
store.subscribe(() => render())
render()
import React, { Component } from 'react'
export const Form = ({ store }) => {
const { text } = store.getState()
return (
<div>
<input
value={text}
onChange={e => store.dispatch({
type: 'CHANGE_TEXT',
text: e.target.value
})}
/>
</div>
)
}
const canvasWidth = 300
const canvasHeight = 50
export class Canvas extends Component {
componentDidMount() {
this.ctx = this.refs.canvas.getContext('2d')
this.ctx.textAlign = 'center'
this.ctx.font = '24px sans-serif'
const { text } = this.props.store.getState()
this.ctx.fillText(text, canvasWidth / 2, canvasHeight / 2)
}
shouldComponentUpdate() {
const { text } = this.props.store.getState()
this.ctx.clearRect(0, 0, canvasWidth, canvasHeight)
this.ctx.fillText(text, canvasWidth / 2, canvasHeight / 2)
return false
}
render() {
return (
<div>
<canvas ref="canvas" width={canvasWidth} height={canvasHeight} />
</div>
)
}
}
Reference
이 문제에 관하여(React/Redux와 요소를 결합하여 사용), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://qiita.com/maiyama18/items/2524b3b898c802a6b97e텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)