2017-05-31 51 views
0

錯誤消息:陣營:現有的狀態轉變期間警告的setState無法更新(如內渲染)

陣營:警告的setState(作爲內渲染例如)不能現有狀態 轉變期間更新

這是一個反應本機應用程序,但我認爲,這是更多的反應問題。

我收到標題中描述的錯誤。但是我對這個原因感到困惑,並且我沒有在父母或孩子的任何部分中設置狀態。所以我有一個grandchild組件(CardLayoutResult),它呈現一個listView,每一行呈現一個新的組件(Render row),它有一個點擊事件,點擊後調用一個函數(onselectLayout)從道具(從父組件傳遞)分量)(父函數setCardTemplate)。這父函數然後調用父內部狀態的setState,然後重新呈現發生。

爲什麼我在點擊收到此錯誤?

父組件

export class Personalization extends Component { 

constructor(props) { 
super(props); 

this.state = { 
    showModel: true, 
    editorState: {} 
}; 

    this.setCardTemplate = this.setCardTemplate.bind(this); 
} 

setCardTemplate(selectedTemplateObj){ 
    console.log(JSON.stringify(selectedTemplateObj)); 
    this.setState({ 
    showModel: false, 
    editorState: selectedTemplateObj 
    }); 
} 

render() { 
    return (
    <View> 
    <CreateCardStep containerState={{showModel:this.state.showModel , 
       editorState: this.state.editorState 
       setCardTemplate:this.setCardTemplate}} /> 
    </View> 
) 
} 

輔元件

const CreateCardStep = (_props) => { 
    return (
    <View> 
     <CardLayoutResults containerState={_props.containerState} /> 
    </View> 
); 
} 

大輔元件

export class CardLayoutResults extends Component { 
    constructor(props) { 
     super(props); 
    } 
    render() { 

    return(

    <View> 
     <ListView 
     RenderRow = {(data) => <RenderRow styles={styles} rowObj={data} onSelectLayout={this.props.containerState.setCardTemplate} /> } 
    </View>  
    ) 
    } 

渲染行

const RenderRow = (props) => { 
    let base64Image = 'data:image/png;base64,'.concat(props.rowObj.base); 

return (
<View style={props.styles.templateImage}> 
    <TouchableHighlight onPress={() => props.onSelectLayout(props.rowObj)}> 
    <Image style={props.styles.thumbnail} resizeMode= {Image.resizeMode.contain} source={{uri: base64Image}}/> 
    </TouchableHighlight> 
</View> 
); 
}; 

- 更新 這個問題似乎設定S1時泰特在setCardTemplate功能

回答

0

您可能需要您的setCardTemplate功能綁定在構造函數或lambda函數調用它(綁定越好)

<View> 
     <ListView renderRow = {(data => rowObj={data}} onSelectLayout={() => this.props.containerState.setCardTemplate} /> 
</View> 
+0

對不起,我已經有了這個綁定。我剛剛編輯了我的帖子。 – user3162979

+0

您''結束標記爲小寫,在CardLayoutResults組件中應該爲大寫。而RenderRow道具應該是renderRow。 – Shota

+0

另外,onSelectLayout不應該在renderRow道具中,而應該是獨立的道具。 – Shota

0

我猜ListView中renderRow不正確稱爲

嘗試

<View> 
    <ListView 
    renderRow = {(data) => <RenderRow rowObj={data} onSelectLayout={this.props.containerState.setCardTemplate} />} 
    /> 
</View> 

和向下傳遞由個性化組件道具等

return (
    <View> 
    <CreateCardStep containerState={{showModel:this.state.showModel , 
       editorState: this.state.editorState 
       setCardTemplate:(val) => this.setCardTemplate(val)}} /> 
    </View> 
) 
+0

沒有運氣。我相信它必須與反應渲染生命週期 – user3162979

0

問題出在您將道具傳遞給父組件的方式。

在這個片段中

<CreateCardStep containerState={{showModel:this.state.showModel , 
      editorState: this.state.editorState 
      setCardTemplate:(val) => this.setCardTemplate(val)}} /> 

同時傳遞函數爲道具本身您呼叫的功能,所以每次組件渲染狀態將被設置這是罰款。

但是,在完成導致此警告的渲染週期之前,當您單擊Render Row組件狀態時,對於同一屬性尚未設置。

修復它只是從父母傳遞函數setCardTemplate: this.setCardTemplate。它會設置狀態(並在內部將調用渲染)只在行按下,而不是每次它被渲染

+0

有意義。但仍然沒有運氣... – user3162979

相關問題