Jake Jeon
Jake Jeon

Reputation: 151

React Redux doesn't update UI

React-Redux doesn't update UI when store changes.

I expect {this.props.isLogged} to get changed dynamically when Change button is clicked.

I searched tons of materials but I cannot find why the text doesn't change when button is clicked.

Index.js

import React from "react";
import ReactDOM from "react-dom";
import App from "./App";
import { createStore } from "redux";
import reducers from "./reducers";
import { Provider } from "react-redux";

const store = createStore(
  reducers);

ReactDOM.render(
  <Provider store={store}>
    <App />
  </Provider>,
  document.getElementById("root")
);

App.js

import React from "react";
import { connect } from "react-redux";
import { loginUser } from "./actions";

class App extends React.Component {
  changeText = () => {
    this.props.loginUser();
  };
  render() {
    return (
      <div>
        <span>{this.props.isLogged}</span>
        <button onClick={this.changeText}>Change</button>
      </div>
    );
  }
}

const mapStateToProps = (state /*, ownProps*/) => {
  return {
    isLogged: state.isLogged
  };
};

const mapDispatchToProps = { loginUser };

export default connect(mapStateToProps, mapDispatchToProps)(App);

./src/reducers/index.js

import { combineReducers } from "redux";
import { LOGIN_USER } from "../actions";

function userReducer(state = { isLogged: false }, action) {
  switch (action.type) {
    case LOGIN_USER:
      return { isLogged: !state.isLogged };
    default:
      return state;
  }
}

const reducers = combineReducers({
  userReducer
});

export default reducers;

./src/actions/index.js

export const LOGIN_USER = "LOGIN_USER";
export function loginUser(text) {
  return { type: LOGIN_USER };
}

Upvotes: 0

Views: 431

Answers (2)

Barun Patro
Barun Patro

Reputation: 860

Check this out.. https://codesandbox.io/s/react-redux-doesnt-update-ui-vj3eh

const reducers = combineReducers({
  userReducer //It is actually userReducer: userReducer
});

As you assiging your UserReducer to userReducer prop, you will have to fetch the same way in mapStateToProps

const mapStateToProps = (state /*, ownProps*/) => {
  return {
    isLogged: state.userReducer.isLogged
  };
};

Also, isLogged prop is a Boolean variable.. So you are gonna have to use toString().

<span>{this.props.isLogged.toString()}</span>

Upvotes: 1

mtkopone
mtkopone

Reputation: 6443

Since you are using combineReducers, the isLogged boolean lives in state.userReducer.isLogged.

Consider changing combineReducers to combineReducers({ user: userReducer }) and accessing the flag with state.user.isLogged.

Upvotes: 0

Related Questions