Reputation: 1039
I have to create a dot page indicator component in react. I first created a dot component, then the actual indicator component . But I have a problem with it.
The state of the indicator component depends on the props that it receives and it as well has to set the state of the individual dots passing down props. To update the state when new props come in I've used componentWillReceiveProps
class PageIndicator extends React.Component{
constructor(props){
super(props);
let pills = [];
for(var i = 0;i<props.size;i++) //Create an array of all the pills required to create the page indicator
if(i == this.props.activeIndice) //Check which of the pills is the active one - active is true
pills.push(<PageIndicatorPill key={i} active={true}/>);
else
pills.push(<PageIndicatorPill key={i} active={false}/>);
this.state = {pills:pills};
}
componentWillReceiveProps(nextProps){
let pills = [];
for (var i = 0; i < nextProps.size; i++) //Update the indicator
if (i == nextProps.activeIndice) //Check which of the pills is the active one - active is true
pills.push(<PageIndicatorPill key={i} active={true} />);
else
pills.push(<PageIndicatorPill key={i} active={false} />);
this.setState({ pills: pills });
}
And here is the dot component
class PageIndicatorPill extends React.Component{
constructor(props){
super(props);
if(this.props.active)
this.state={image : onState};
else
this.state = { image: offState };
this.style = {
backgroundImage:`url(${this.state.image})`,
marginRight:'10px',
height:"32px",
width:"32px" ,
display:"inline-block"};
}
componentWillReceiveProps(nextProps){
if (nextProps.active)
this.setState({ image: onState });
else
this.setState({image : offState});
}
If I go ahead and console log the states, they update, but the problem is that the component doesn't seem to re-render accordingly and I can't figure out why. Can you help me out please?
Upvotes: 1
Views: 178
Reputation: 2189
Your state is updating, however you only set your styles in the constructor of your PageIndicatorPill
component. this.style
would need to be updated within the componentWillReceiveProps
method.
However.. This can be simplified a lot from the example you have provided. There is no need to mirror the active prop in state as image
. You could do something like:
class PageIndicatorPill extends React.Component{
getStyle() {
const { active } = this.props;
return {
backgroundImage: `url(${active ? onState : offState})`,
marginRight: '10px',
height: '32px',
width: '32px',
display: 'inline-block'
};
}
render() {
return (
<div style={this.getStyle()} />
);
}
}
You didn't post a render function so this example is just a simple demonstration of using props directly to get the styles, but hopefully the above makes sense.
Your other component can also be simplified and not need state...
class PageIndicator extends React.Component{
getPills() {
const { size, activeIndice } = this.props;
let pills = [];
for (let i = 0; i < size; i++) {
pills.push(
<PageIndicatorPill key={i} active={i === activeIndice} />
);
}
return pills;
}
render() {
return (
<div>
{this.getPills()}
</div>
);
}
}
Upvotes: 1