React child 组件 Re-renders 没有状态变化
React child component Re-renders without state change
我正在将一些数据从一个组件传递到另一个组件(parent 到 child)。输入和按钮单击事件的数据传递没有任何问题。我通过考虑一些关键事件(是否输入数字)添加了一些验证。当与此验证相关的特定功能被触发时,child 组件会自动 re-renders。我不知道为什么。这是我的代码。我用过助焊剂架构。
主要Parent(关键事件发生的地方)
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;
状态发生变化的 child 组件
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;
这里渲染函数被触发,即使状态没有被child components.I 调试的通量文件改变它们正常工作。我遇到这个问题的任何原因
`Here the render function get triggered even though the states are
not changed by the child components
据我了解,您有一个 setState 函数可以触发重新渲染 PaserBox,但您不希望它导致重新渲染作为 PaserBox 子级的 ParserTreeBox
如果是的话ParserTreeBox重新渲染是很正常的,因为PaserBox的渲染函数包含了ParserTreeBox组件
当它在PaserBox的渲染函数中时,它只是传递数据。但是你仍然可以忽略 ParserTreeBox 组件在 ParserTreeBox 端重新渲染 shouldComponentUpdate(nextProps, nextState) 函数。
shouldComponentUpdate(nextProps, nextState){
return this.state.taggedData == nextState.taggedData ? false : true
}
现在它将在决定此组件的渲染后检查此方法。
将Component
更改为PureComponent
:
class MyComponent extends React.Component {
// ...
class MyComponent extends React.PureComponent {
// ...
它通过浅层 prop
和 state
比较实现 shouldComponentUpdate()
。
我正在将一些数据从一个组件传递到另一个组件(parent 到 child)。输入和按钮单击事件的数据传递没有任何问题。我通过考虑一些关键事件(是否输入数字)添加了一些验证。当与此验证相关的特定功能被触发时,child 组件会自动 re-renders。我不知道为什么。这是我的代码。我用过助焊剂架构。
主要Parent(关键事件发生的地方)
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;
状态发生变化的 child 组件
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;
这里渲染函数被触发,即使状态没有被child components.I 调试的通量文件改变它们正常工作。我遇到这个问题的任何原因
`Here the render function get triggered even though the states are
not changed by the child components
据我了解,您有一个 setState 函数可以触发重新渲染 PaserBox,但您不希望它导致重新渲染作为 PaserBox 子级的 ParserTreeBox
如果是的话ParserTreeBox重新渲染是很正常的,因为PaserBox的渲染函数包含了ParserTreeBox组件
当它在PaserBox的渲染函数中时,它只是传递数据。但是你仍然可以忽略 ParserTreeBox 组件在 ParserTreeBox 端重新渲染 shouldComponentUpdate(nextProps, nextState) 函数。
shouldComponentUpdate(nextProps, nextState){
return this.state.taggedData == nextState.taggedData ? false : true
}
现在它将在决定此组件的渲染后检查此方法。
将Component
更改为PureComponent
:
class MyComponent extends React.Component {
// ...
class MyComponent extends React.PureComponent {
// ...
它通过浅层 prop
和 state
比较实现 shouldComponentUpdate()
。