Reputation: 362
I am using React 16 with Redux and i am using this.setState func onClick. But it is not working correctly. I tried to debug for hours and could not find any solution. Here is my code;
import React, { Component } from 'react';
import PropTypes from 'prop-types';
class SSelect extends Component {
state = {
selectedName: '',
}
handleSelect = (id, name) => {
this.setState({ selectedName: name });
this.props.handleSelect(id); // this is redux action
}
render() {
console.log(this.state.selectedName);
return (
<div>
{
this.props.options.map(option => (
<div
key={option.id}
role="button"
onKeyPress={() => this.handleSelect(option.id, option.name)}
onClick={() => this.handleSelect(option.id, option.name)}
tabIndex="0"
>
{option.name}
</div>
))
}
</div>
);
}
}
SSelect.propTypes = {
handleSelect: PropTypes.func.isRequired,
options: PropTypes.array.isRequired,
segmentIndex: PropTypes.number,
};
SSelect.defaultProps = {
segmentIndex: 0,
};
export default onClickOutside(SSelect);
console.log(this.state.selectedName);
prints nothing, if i select same option on list, it prints true result. After select a new option, it prints empty again.
when i track my redux processes, i saw that it is working and sets new value to store correctly. when i remove my redux action, console.log(this.state.selectedName);
printing true value.
here is my react and redux versions;
"react": "^16.2.0",
"react-redux": "^5.0.6",
"redux": "^3.7.2",
Thank you for your help.
Upvotes: 0
Views: 124
Reputation: 545
To solve this problem a simple way, You can set the selectedName
manually and then you can do force update.
handleSelect(id, name) {
this.state.selectedName=name;
this.forceUpdate();
this.props.handleSelect(id);
}
To redux setState
handleSelect(id,name){
this.setState({ selectedName: name })
};
onClick={this.handleSelect.bind(this,option.id, option.name)}
Upvotes: 1
Reputation: 362
This is very strange but i solved the problem.
On my reducer, my key's name was segment
. I converted the name to selectedSegment
and problem solved. I think segment
word is reserved but i could not find any doc about reserved words.
I will open an issue to react-redux
Thank you all
Upvotes: 0
Reputation: 2721
I suppose you wrap the component with connect()
?
As far is I know connect()
makes you component pure
(in redux terminology - props only) by default. It can be overridden in the fourth options
argument of connect
.
However most likely the best solution would be to get rid of internal state, because that's what we use redux for
[options] (Object) If specified, further customizes the behavior of the connector. In addition to the options passable to connectAdvanced() (see those below), connect() accepts these additional options:
[pure] (Boolean): If true, connect() will avoid re-renders and calls to mapStateToProps, mapDispatchToProps, and mergeProps if the relevant state/props objects remain equal based on their respective equality checks. Assumes that the wrapped component is a “pure” component and does not rely on any input or state other than its props and the selected Redux store’s state. Default value: true
https://github.com/reactjs/react-redux/blob/master/docs/api.md
Upvotes: 0
Reputation: 55643
Unless my eyes are deceiving me, you have defined handleSelect
as a class method and not an instance method meaning the this
inside of the handleSelect
function you have defined does not refer to your component.
You should define it as:
handleSelect(id, name) {
this.setState({ selectedName: name });
this.props.handleSelect(id); // this is redux action
}
rather than:
handleSelect = (id, name) => {
this.setState({ selectedName: name });
this.props.handleSelect(id); // this is redux action
}
Upvotes: 0