我将一些数据从一个组件传递到另一个组件(父对子)。输入和按钮单击事件传递的数据没有任何问题。我通过考虑一些关键事件(是否输入了数字)添加了一些验证。当触发与此验证相关的特定功能时,子组件自动重新呈现。我无法弄清楚为什么。这是我的代码。我使用了通量架构。
主要的父母(发生关键事件的地方)
const validatebox = (textStatus) => {
if (textStatus.length > 100) {
return {
error: '*status is too long',
};
} else if (textStatus === '') {
return {
error: '*status cannot be empty',
};
} else {
return true;
}
}
class PaserBox extends React.Component{
constructor(props) {
super(props);
this.state = {
textStatus: '',
tags:{},
showResults: false
};
}
parse = () => {
let status = this.refs.textinput.getValue();
if(validatebox(status).error) {
this.setState({
textStatus: validatebox(status).error
});
return;
}
else {
Actions.SendDataToTag(status);
this.setState({ showResults: true });
console.log(status);
}
this.clearText();
};
clearText = () => {
document.getElementById('language').value = '';
};
handleKey = (e) =>{
if (e.key === 'Enter') {
this.parse();
}
else {
var keycode = e.which;
if ((e.shiftKey == false && (keycode == 46 || keycode == 8 || keycode == 37 || keycode == 39 || (keycode >= 48 && keycode <= 57)))) {
this.setState({
textStatus: 'cannot enter numbers'
});
}
else {
this.setState({
textStatus: ''
});
}
}
};
handleKeyDown = (e) => {
if (e.keyCode == 8) {
this.setState({
textStatus: ''
});
}
};
render(){
return(
<div>
<Paper className="row col-xs-12 col-sm-12 col-md-12" style={style} zDepth={1}>
<div className="col-xs-12 col-sm-12 col-md-12 col-lg-12">
<TextField
fullWidth={true}
style={textfieldstyle}
errorText={this.state.textStatus}
ref="textinput"
onKeyPress={this.handleKey}
onKeyDown={this.handleKeyDown}
hintText="Enter sentence ..."
className="col-xs-12 col-sm-12 col-md-12"
name="ta"
id="language"/>
</div>
<div className="col-xs-9 col-sm-9 col-md-9"/>
<div className="col-xs-3 col-sm-3 col-md-3" style={style_button}>
<RaisedButton secondary={true} label="Parse" onTouchTap={this.parse}/>
</div>
<div className="col-xs-1 col-sm-1 col-md-1"/>
</Paper>
<label style={styles}>Please enter sentences with correct grammar</label>
<br/>
{ this.state.showResults ? <div className="row">
<div className="col-md-10">
<ParserTreeBox/>
</div>
<div className="col-md-2">
<ParserTags/>
</div>
</div> : null }
</div>
);
}
}
export default PaserBox;
状态发生变化的子组件
class ParserTreeBox extends React.Component{
constructor(props) {
super(props);
this.state = {
data: [],
taggedData:{}
}
this._onChange = this._onChange.bind (this);
}
componentWillMount(){
Store.addChangeListener(this._onChange);
}
componentWillUnmount(){
Store.removeChangeListener(this._onChange);
}
_onChange(){
this.setState({taggedData:Store.getData()});
}
render(){
return(
<div>
<div>
<ParserTree data={this.state.taggedData} />
</div>
</div>
);
}
}
export default ParserTreeBox;
这里渲染函数会被触发,即使子组件没有改变状态。我调试了它们正常工作的磁通文件。我得到这个问题的任何原因
答案 0 :(得分:1)
`这里即使状态为
,渲染函数也会被触发 没有被子组件改变
据我所知,你有一个setState函数触发重新渲染PaserBox,你不希望它导致重新渲染ParserTreeBox,这是PaserBox的孩子
如果是这样,ParserTreeBox重新渲染是很正常的,因为PaserBox的渲染函数包含ParserTreeBox组件。
当它在PaserBox的渲染功能中时,它只传递数据。但你仍然可以忽略ParserTreeBox组件在ParserTreeBox端重新渲染shouldComponentUpdate(nextProps,nextState)函数。
shouldComponentUpdate(nextProps, nextState){
return this.state.taggedData == nextState.taggedData ? false : true
}
现在它将在确定此组件的渲染后检查此方法。
答案 1 :(得分:1)
将Component
更改为PureComponent
:
class MyComponent extends React.Component {
// ...
class MyComponent extends React.PureComponent {
// ...
它通过浅shouldComponentUpdate()
和prop
比较来实现state
。