1

I think this question has been answer several time but I can't find my specific case.

https://codesandbox.io/s/jjy9l3003

So basically I have an App component that trigger an action that change a state call "isSmall" to true if the screen is resized and less than 500px (and false if it is higher)

class App extends React.Component {
...
resizeHandeler(e) {
    const { window, dispatch } = this.props;
    if (window.innerWidth < 500 && !this.state.isSmall) {
      dispatch(isSmallAction(true));
      this.setState({ isSmall: true });
    } else if (window.innerWidth >= 500 && this.state.isSmall) {
      dispatch(isSmallAction(false));
      console.log(isSmallAction(false));
      this.setState({ isSmall: false })
    }
  };

  componentDidMount() {
    const { window } = this.props;
    window.addEventListener('resize', this.resizeHandeler.bind(this));
  }
...

I have an other component called HeaderContainer who is a child of App and connected to the Store and the state "isSmall", I want this component to rerender when the "isSmall" change state... but it is not

class Header extends React.Component {

  constructor(props) {
    super(props);

    this.isSmall = props.isSmall;
    this.isHome = props.isHome;
  }
  ...
  render() {
     return (
      <div>
        {
          this.isSmall
          ?
           (<div>Is small</div>)
          :
           (<div>is BIG</div>)
        }
      </div>
    );
   }
   ...

even if I can see through the console that redux is actually updating the store the Header component is not re-rendering. Can someone point out what I am missing ?

Am I misunderstanding the "connect()" redux-react function ?

2 Answers 2

2

Looking at your code on the link you posted your component is connected to the redux store via connect

const mapStateToProps = (state, ownProps) => {
  return {
    isHome: ownProps.isHome,
    isSmall: state.get('isSmall')
  }
}


export const HeaderContainer = connect(mapStateToProps)(Header);

That means that the props you are accessing in your mapStateToProps function (isHome and isSmall) are taken from the redux store and passed as props into your components.

To have React re-render your component you have to use 'this.props' inside the render function (as render is called every time a prop change):

render() {
     return (
      <div>
        {
          this.props.isSmall
          ?
           (<div>Is small</div>)
          :
           (<div>is BIG</div>)
        }
      </div>
    );
   }

You are doing it well in the constructor but the constructor is only called once before the component is mounted. You should have a look at react lifecycle methods: https://reactjs.org/docs/react-component.html#constructor

You could remove entirely the constructor in your Header.js file.

You should also avoid using public class properties (e.g. this.isSmall = props.isSmall; ) in react when possible and make use of the React local state when your component needs it: https://reactjs.org/docs/state-and-lifecycle.html#adding-local-state-to-a-class

Sign up to request clarification or add additional context in comments.

Comments

1

A component is only mounted once and then only being updated by getting passed new props. You constructor is therefore only being called once before mount. That means that the instance properties you set there will never change during the lifetime of your mounted component. You have to directly Access this.props in your render() function to make updating work. You can remove the constructor as he doesn't do anything useful in this case.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.