首页 文章

更改状态后,React-Redux连接组件不会更新

提问于
浏览
1

我正在尝试使用React-Redux . 我有一种情况,其中一个连接组件( Coordinates.jsx )嵌套在另一个连接组件( Canvas.jsx )中 .

源代码https://github.com/RinatRezyapov/Vault-13.git(纱线安装然后纱线启动)

在父组件 Canvas.jsx 中,我在 componentDidMount() 中调度一个不可改变状态的动作 .

Canvas.jsx

componentDidMount() { this.props.addCanvasSize(windowWidth, windowHeight) }

问题是在更改状态后,子组件 Coordinates.jsx 没有更新,console.log显示 undefined .

Coordinates.jsx

componentDidMount() { console.log(this.props.canvasSize) }

我确信状态是正确更新的(使用Redux devTool检查),我想我没有改变状态 .

如果我在setTimeout中包装console.log(this.props.canvasSize),那么它会显示coorect状态 .

index.js (store)

const store = createStore(reducer,
window.__REDUX_DEVTOOLS_EXTENSION__ && window.__REDUX_DEVTOOLS_EXTENSION__())

render(
<Provider store={store}>
<App />
</Provider>, 
document.getElementById('root'));

actions/index.js

export const addCanvasSizeAction = (windowWidth, windowHeight) => ({
type: 'ADD_CANVAS_SIZE',
windowWidth,
windowHeight
})

reducers/reducer.js

export const reducer = (state={}, action) => {
switch (action.type) {
    case 'ADD_CANVAS_SIZE':
    return Object.assign({}, state, {canvasSize: {canvasWidth: action.windowWidth, canvasHeight: action.windowHeight}})
    default: 
    return state
}
}

components/App.jsx

class App extends React.Component {
render() {
return (  
    <div>
            <CanvasCont />
    </div>
    )
}
}

components/Canvas.jsx

class Canvas extends React.Component {
constructor(props) {
super(props);

}


componentDidMount() {
var windowWidth = window.innerWidth-100;
var windowHeight = window.innerHeight-100;
var createCanvas = document.createElement("canvas");
createCanvas.id = 'canvas';
createCanvas.width = windowWidth;
createCanvas.height = windowHeight;
ReactDOM.findDOMNode(this).appendChild(createCanvas);
var rect = canvas.getBoundingClientRect();
var ctx = createCanvas.getContext('2d');
 this.props.addCanvasSize(windowWidth, windowHeight)    
}



render() {
return (<div>
<CoordinatesCont />
</div>)
}
}

components/Coordinates.jsx

class Coordinates extends React.Component {

constructor(props) {
    super(props);

}
componentDidMount() {
console.log(this.props.canvasSize)
}
render() {

    var inlineStyle={
        width: "800px",
        height: "600px"
    }
       return (
    <div >
<span  style={inlineStyle} onMouseMove={this.handleMouseMove}></span>
    </div>
)
}
}

containers/CanvasCont.js

const mapStateToProps = (state) => ({
state: state
})

const mapDispatchToProps = (dispatch) => ({
addCanvasSize: (windowWidth, windowHeight) => 
{dispatch(addCanvasSizeAction(windowWidth, windowHeight))}
})

const CanvasCont = connect(
mapStateToProps,
mapDispatchToProps
)(Canvas)

containers/CoordinatesCont.js

const mapStateToProps = (state) => ({
canvasSize: state.canvasSize
})

const mapDispatchToProps = (dispatch) => ({
})

const CoordinatesCont = connect(
mapStateToProps,
mapDispatchToProps
)(Coordinates)

1 回答

  • 2

    在处理父/子关系时,你应该记住,在孩子被调用之前,孩子会调用 componentDidMount (如本答案https://stackoverflow.com/a/38472793/2745879中所述)

    所以实际上在你的情况下,这是发生的事情:

    • 孩子触发了 componentDidMount 回调,但状态尚未定义

    • 你的 console.log 被触发但 props 中没有任何内容

    • 父级触发 componentDidMount 并更新状态

    • 如果您在孩子的超时中调用 console.log ,现在您的属性是最新的

    现在,如果要解决此问题,则需要使用 componentWillReceiveProps 回调,只要为组件指定了新属性,就会调用该回调 . https://facebook.github.io/react/docs/react-component.html#componentwillreceiveprops

相关问题