2017-05-24 49 views
1

我正在嘗試使用React-Redux。我有一種情況,其中一個連接組件(Coordinates.jsx)嵌套在另一個連接組件(Canvas.jsx)中。React-Redux連接組件在狀態更改後未得到更新

源代碼https://github.com/RinatRezyapov/Vault-13.git(紗線安裝,然後紗線開始)

在父組件Canvas.jsx我分派在componentDidMount()其中一成不變改變狀態的動作。

Canvas.jsx

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

的問題是,改變狀態的子組件Coordinates.jsx沒有更新和執行console.log後顯示不確定

Coordinates.jsx

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

我敢肯定,狀態正確更新(與終極版devTool檢查),我想我並沒有減少變異狀態。

如果我在setTimeout中包裝了console.log(this.props.canvasSize),那麼它顯示了coorect狀態。

index.js(存儲)

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

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

動作/ index.js

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

減速器/ 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 
} 
} 

組件/ App.jsx

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

組件/ 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>) 
} 
} 

組件/ 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> 
) 
} 
} 

容器/ 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解釋)其實在你的情況下,會出現以下情況:

  1. 孩子觸發其componentDidMount回調,但尚未定義的狀態
  2. console.log被觸發,但沒有什麼在props
  3. 父觸發其componentDidMount,如果你在孩子超時調用console.log更新狀態
  4. ,現在你的屬性都是最新現在

如果你想解決這個問題,你需要使用componentWillReceiveProps回調函數,這個回調函數在組件被賦予新屬性時會被調用。 https://facebook.github.io/react/docs/react-component.html#componentwillreceiveprops

+0

不知道孩子的componentDidMount是否先被調用。感謝您的信息,現在我看到會發生什麼。這意味着在這種情況下,更新子組件的唯一方法是檢查nextProps,然後強制更新組件?有沒有其他方法可以使組件保持狀態?也許巢畫布和座標應用程序組件(我的意思是擺脫父母/孩子的關係?) –

+0

哦,不,我不認爲你必須改變任何東西。爲了確信一切都按預期工作,試着在子組件的'render'函數中添加一個'console.log(this.props)',你會看到(如果我是正確的)2個日誌,第一個是'未定義「,另一個具有正確的'canvasSize'值 – atomrc

+0

@GalaxyWanderer它是有道理的,雖然,對吧?父組件的子組件必須先掛載,然後才能考慮掛載父組件。 –