我希望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事物上而触发的。)
答案 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)
我认为您的回答是您的第二个观察。 [未通过父母的状态更新触发捐款]。猜猜是什么触发了来自父级的触发?道具
因此,与其将您的值置于状态中,不如将其置于属性中,这样,如果父级对其进行了更改,则您的组件也会发生变化。
希望这会有所帮助