Javascript React Redux连接的组件不';状态更改后无法更新

Javascript React Redux连接的组件不';状态更改后无法更新,javascript,reactjs,redux,react-redux,Javascript,Reactjs,Redux,React Redux,我正在尝试使用React Redux。我遇到一种情况,一个连接的组件(Coordinates.jsx)嵌套在另一个连接的组件(Canvas.jsx)中 源代码(纱线安装,然后纱线启动) 在父组件Canvas.jsx中,我在componentDidMount()中调度一个操作,该操作不可变地更改状态 Canvas.jsx componentDidMount(){ this.props.addCanvasSize(窗口宽度、窗口高度) } 问题是在更改状态后,子组件坐标.jsx不会得到更新,并且co

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

源代码(纱线安装,然后纱线启动)

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

Canvas.jsx

componentDidMount(){
this.props.addCanvasSize(窗口宽度、窗口高度)
}

问题是在更改状态后,子组件坐标.jsx不会得到更新,并且console.log显示未定义

Coordinates.jsx

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

我确信状态已正确更新(使用Redux devTool进行检查),并且我猜我没有在reduce中对状态进行变异

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

index.js(商店)

减速器/reducer.js

export const addCanvasSizeAction = (windowWidth, windowHeight) => ({
type: 'ADD_CANVAS_SIZE',
windowWidth,
windowHeight
})
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
}
}
const mapStateToProps = (state) => ({
state: state
})

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

const CanvasCont = connect(
mapStateToProps,
mapDispatchToProps
)(Canvas)
const mapStateToProps = (state) => ({
canvasSize: state.canvasSize
})

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

const CoordinatesCont = connect(
mapStateToProps,
mapDispatchToProps
)(Coordinates)
组件/App.jsx

class App extends React.Component {
render() {
return (  
    <div>
            <CanvasCont />
    </div>
    )
}
} 
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>)
}
}
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>
)
}
}
容器/CoordinatesCont.js

export const addCanvasSizeAction = (windowWidth, windowHeight) => ({
type: 'ADD_CANVAS_SIZE',
windowWidth,
windowHeight
})
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
}
}
const mapStateToProps = (state) => ({
state: state
})

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

const CanvasCont = connect(
mapStateToProps,
mapDispatchToProps
)(Canvas)
const mapStateToProps = (state) => ({
canvasSize: state.canvasSize
})

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

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

在处理父/子关系时,您应该记住,在对父级调用
组件didmount
之前,先对子级调用它(如本答案中所述)

实际上,在你的情况下,发生了以下情况:

  • 子级触发其
    组件didmount
    回调,但状态尚未定义
  • 您的
    控制台.log
    被触发,但
    道具中没有任何内容
  • 父级触发其
    组件didmount
    并更新状态
  • 如果在子级中超时调用
    console.log
    ,则现在您的属性是最新的

  • 现在,如果您想解决这个问题,您需要使用
    componentWillReceiveProps
    回调,每当为组件提供新属性时,就会调用该回调

    请将诊断潜在问题所需的代码放在帖子中,而不是指向外部存储库。它的连接方式很重要,状态形状很重要。我不知道孩子的组件didmount是第一个被调用的。谢谢你提供的信息,现在我知道会发生什么了。这意味着在这种情况下,更新子组件的唯一方法是检查nextProps,然后强制更新组件?是否有其他方法使组件保持最新状态?也许应用程序组件中的嵌套画布和坐标(我的意思是摆脱父/子关系?)。要确信一切都按预期工作,请尝试在子组件的
    渲染
    功能中添加
    console.log(this.props)
    ,您将看到(如果我是正确的)2个日志第一个日志是
    未定义的
    ,另一个日志具有正确的
    画布大小
    value@GalaxyWanderer但这是有道理的,正确的?必须先装入组件的子组件,然后才能考虑装入父组件。