组件未在stateChange

时间:2018-07-31 03:40:38

标签: reactjs

我希望TextField的值是一些计算值...因此,我有一个受控形式ComputedValue,其呈现方法如下:

render() {
    return <TextField
        value={this.state.value}
        key={this.props.id}
        id={this.props.id}
        label={this.props.label}
        inputProps={{
            readOnly: true
        }}
    />;
}

ComputedValue的state.value是通过从localStorage提取数据,进行一些计算并设置状态来设置的。该方法如下所示:

computeValue() {
    let computedValue="";

    // split the computation string into constituent components
    let splitCS = this.props.computationString.split(/([+,-,*,/,(,),^])/g);

    // replace all instaces of questionID's with their value
    for (let i = 0; i < splitCS.length; i++) {
        if (splitCS[i] !== '+' && splitCS[i] !== '-' && splitCS[i] !== '*' &&   splitCS[i] !== '/' &&
            splitCS[i] !== '(' && splitCS[i] !== ')' && splitCS[i] !=='^') {
                // splitCS[i] is a questionID
                let Q = getQuestionDataFromLSbyQuestionID(splitCS[i]); 
                splitCS[i] = Q.value;
            }
    }

    // check that all values returned 
    if(splitCS.includes("")) {
        console.log("null value was returned in ComputedValue question");
    } else {
        // rejoin string and send to eval (TODO: replace eval)
        let finalComputeString = splitCS.join('')
        computedValue = eval(finalComputeString);
    }

    // save value in state
    this.setState({
        value: computedValue
    }, () => {
        this.props.stateChangeHandler(this);
        this.render();
    }
    );

    return computedValue;
}

此组件是问题树中的叶子;当它们的值更改时(我的应用同步LS和父级的状态),我希望计算的值更改。

这是我的两个问题:

1)鉴于我在computeValue函数内调用了setState,因此无法从render函数内调用它。但是,如果仅从componentWillMount生命周期函数调用它,则computeValue仅被调用一次(在安装时),然后不再被调用。如果从componentWillUpdate调用它,则会遇到无限循环。我可以通过比较nextState和其他状态来停止循环,但这似乎不是最好的方法。

2)渲染不是由父级状态的更新触发的。包括尝试“ forceUpdate”)(尽管它们似乎确实是由于悬停在鼠标和其他各种UI事物上而触发的。)

2 个答案:

答案 0 :(得分:2)

  

鉴于我在computeValue函数中调用了setState ...我无法   从render函数中调用它。

我希望您阐述或阐明这一陈述。

  

但是,如果我仅从componentWillMount生命周期调用它   函数,computeValue仅被调用一次(安装时),并且   然后不再。

是的,componentWillMount是一个生命周期挂钩,当要在树中添加该组件时,它仅被调用一次。

  

如果从componentWillUpdate调用它,则会出现无限循环。

在更新组件之前,将调用此生命周期挂钩。因此,如果您在此处设置状态,它将再次调用此函数,并且将导致无限循环。

  

我可以通过比较nextStates和其他内容来停止此循环...   但这似乎不是最好的方法。

您始终可以进行比较并更新状态。这样做没有错。

  

渲染不由父母状态的更新触发。   包括尝试“ forceUpdate”)

永远不要显式调用render。这不是正确的做法,因为它会阻碍正常的反应流。

我希望您测试setstate

this.setState(() => ({
    value: computedValue
}), () => {
    console.log("working")
    this.props.stateChangeHandler(this);
}
);

问题似乎出在()中的({ value: computedValue })。试试看。

答案 1 :(得分:0)

我认为您的回答是您的第二个观察。 [未通过父母的状态更新触发捐款]。猜猜是什么触发了来自父级的触发?道具

因此,与其将您的值置于状态中,不如将其置于属性中,这样,如果父级对其进行了更改,则您的组件也会发生变化。

希望这会有所帮助