Reputation: 4481
Im passing some data from one component to another (parent to child). The data is passed without any issue from the enter and button click event. I have added some validations by considering some key events (whether numbers are entered). When ever the particular function related to this validation is triggered the child component auto manically re-renders. I cannot figure out why. here is my code. I have used flux architecture.
the main Parent(where keyevent takes place)
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;
the child component where the states change happens
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;
Here the render function get triggered even though the states are not changed by the child components.I debugged the flux files they are working properly. Any reason why im getting this issue
Upvotes: 0
Views: 158
Reputation: 6957
Change Component
to PureComponent
:
class MyComponent extends React.Component {
// ...
class MyComponent extends React.PureComponent {
// ...
It implements shouldComponentUpdate()
with both a shallow prop
and state
comparison.
Upvotes: 1
Reputation: 1690
`Here the render function get triggered even though the states are
not changed by the child components
As far as I understand you have a setState function which triggers re render PaserBox and you don't want it to cause re render of ParserTreeBox which is child of PaserBox
If so it is quite normal that ParserTreeBox re renders because render function of PaserBox includes ParserTreeBox component.
When it is in render function of PaserBox it just passes data. But you can still neglect ParserTreeBox component re rendering shouldComponentUpdate(nextProps, nextState)function on ParserTreeBox side.
shouldComponentUpdate(nextProps, nextState){
return this.state.taggedData == nextState.taggedData ? false : true
}
now it will check this method after that rendering of this component will be decided.
Upvotes: 1