storybookjs / storybook

Storybook is the industry standard workshop for building, documenting, and testing UI components in isolation
https://storybook.js.org
MIT License
84.09k stars 9.25k forks source link

How to use redux props/state in react state? #15695

Closed sajjadshiasi closed 3 years ago

sajjadshiasi commented 3 years ago

I try to pass data from redux props but get undefined and null instead. In react dev tools there are data and I see them. But when I try to set email from props to state I have error that cannot read property ‘email’ of undefined This is my component code :

`

      class RegisterFinal extends Component {

          componentDidMount() {
              store.dispatch(loadUser());

          }
          componentWillReceiveProps(nextProps) {
              if (nextProps.user !== this.props.user) {
                  this.setState({ email: nextProps.user});
              }
          }

          state = {
              userName: "",
              password: "",
              passwordConfirm: "",
              email: "",
              msg: null
          }

          static propTypes = {
              isAuthenticated: PropTypes.bool,
              setPass: PropTypes.bool,
              register: PropTypes.func.isRequired,
              auth: PropTypes.object.isRequired,
              user : PropTypes.object.isRequired,
          };

          onSubmit = (e) => {
              e.preventDefault();
              const {password, userName, email} = this.state
              const setPass = {
                  password, userName, email
              }
              this.props.setPass(setPass);
              const {passwordConfirm} = e.target;
              const errors = {};
              if (password.value !== passwordConfirm.value) {
                  errors.passwordMismatch = "Entered passwords do not match.";
                  console.log(errors)
              }
          }
          onChange = (e) => {
              this.setState({
                  [e.target.name]: e.target.value,
              });
          };

          render() {
              return (
                  <div className={"container"}>
                      <div className={"row row-of-final-register justify-content-center"}>
                          <div className={"mt-5 register-teacher-inputs-box final-register-teacher-inputs-box"}>
                              <div className={"final-register-wrapper"}>

                              <form className={"mt-5"} onSubmit={this.onSubmit}>
                                  <div className={"row"}>
                                      <div className={"col-12"}>
                                          <label
                                              htmlFor={"userName"} className={"text-right username-label"}>
                                              <span>*</span>
                                          </label>
                                          <input type="text" className="form-control w-100" placeholder={"Username"}
                                                 name={"userName"}
                                                 autoComplete="true"
                                                 value={this.userName}
                                                 onChange={this.onChange}
                                                 onFocus={(e) => e.target.placeholder = ""}
                                          />
                                      </div>
                                  </div>
                                  <div className={"row"}>
                                      <div className={"col-12 col-lg-6 mt-3"}>
                                          <label
                                              htmlFor={"password"} className={" text-right"}>
                                              <span>*</span>
                                          </label>
                                          <input type="password" className="form-control " placeholder={"Password"}
                                                 name={"password"}
                                                 value={this.password}
                                                 onChange={this.onChange}

                                                 onFocus={(e) => e.target.placeholder = ""}
                                          />
                                      </div>

                                  </div>
                                  <div className={"row mt-3 pt-2"}>
                                      <div className={"col-12 final-register-wrapper final-register-btn"}>
                                          <button type={"submit"} className={"final-register-btn"}>Submit</button>
                                      </div>
                                  </div>
                              </form>
                          </div>
                      </div>
                  </div>
              )
          }
      }

      function mapStateToProps (state , ownProperties)  {
          console.log(state.auth.user)
          return {
              setPass: state.auth.setPass,
              isAuthenticated: state.auth.isAuthenticated,
              error: state.error,
              auth: state.auth,
              user : state.auth.user,

          }

      };
      function mapDispatchToProps(dispatch) {
          return bindActionCreators(actionCreators, dispatch);
      }
      export default connect(mapStateToProps, mapDispatchToProps

      )(RegisterFinal);

` I just change email : this.props.user to email : this.props.user.email in componentWillReceiveProps. I actually need to set redux props to react state. When I give log from componentWillReceivePropsreturn to me undefined after null.

This is my reducer code : `

              const initialState = {
                  token: localStorage.getItem("token"),
                  isAuthenticated: null,
                  isLoading: false,
                  verifyCode : null,
                  setPass : null,
                  user: null,
              };

              export default function (state = initialState , action) {
                  switch (action.type) {
                      case USER_LOADING:
                          return {
                              ...state,
                              isLoading: true,
                              user: action.payload
                          };
                      case USER_LOADED:
                          return {
                              ...state,
                              isAuthenticated: true,
                              isLoading: false,
                              verifyCode: true,
                              user: action.payload,
                          };
                      case LOGIN_SUCCESS:
                      case REGISTER_SUCCESS:
                          localStorage.setItem("token", action.payload.token);
                          return {
                              ...state,
                              ...action.payload,
                              isAuthenticated: true,
                              isLoading: false,
                              verifyCode: false
                          };
                      case SET_PASS_FAIL:
                      case AUTH_ERROR:
                      case LOGIN_FAIL:
                      case VERIFY_FAIL:
                          return {
                              ...state,
                              verifyCode: false,
                              isLoading: true
                          }
                      case VERIFY_CODE :
                          return {
                              ...state,
                              user: action.payload,
                              verifyCode: true,
                              isAuthenticated: true,
                              isLoading: false
                          };
                      case SET_PASS :
                          return {
                              ...state,
                              user: action.payload,
                              isAuthenticated: true,
                              isLoading: false,
                              setPass: true,
                          }
                      case LOGOUT_SUCCESS:
                          localStorage.removeItem("token");
                          return {
                              token: null,
                              user : null,
                              isAuthenticated: false,
                              isLoading: true
                          }
                      case REGISTER_FAIL:
                          localStorage.removeItem("token");
                          return {
                              ...state,
                              token: null,
                              user: null,
                              isAuthenticated: false,
                              isLoading: false,
                          };
                      default:
                          return state;
                  }
              }`

And this my app.js file : ` import React, {Component} from "react"; import {Router, Route, Switch, BrowserRouter} from "react-router"; import { Navigation, Footer, Home, About, Download, Support, Blog, Login, StudentRegister, Audit } from "../src/components"; import Register from "../src/components/Register" import CheckCode from "../src/components/register/CheckCode"; import TeacherProfile from "./components/TeacherProfile/TeacherProfile"; import RegisterFinal from "./components/register/RegisterFinal" import PrivateRoute from "./components/PrivateRoute/PrivateRouting"; import store from "./store"; import {Provider} from "react-redux"; import {ToastContainer} from "react-toastify"; import "react-toastify/dist/ReactToastify.css"; import {createBrowserHistory} from "history";

                                        export const history = createBrowserHistory();

                                        class App extends Component {

                                            render() {
                                                return (
                                                    <Provider store={store}>
                                                        <ToastContainer/>
                                                        <div className="App">
                                                            <Router history={history}>
                                                                <Navigation/>
                                                                    <Switch>
                                                                        <Route path="/" exact component={() => <Home/>}/>

                                                                       <PrivateRoute exact path={"/profile"} component={TeacherProfile}/>
                                                                        <PrivateRoute exact path={"/register/register-final"} component={RegisterFinal}/>

                                                                    </Switch>
                                                                <Footer/>
                                                            </Router>
                                                        </div>
                                                    </Provider>
                                                );
                                            }
                                        }

                                        export default App;`

This is my store code : ` import { createStore, applyMiddleware, compose } from "redux"; import thunk from "redux-thunk"; import combineReducers from "./reducers";

                                          const initialState = {};

                                          const middleware = [thunk];

                                          const store = createStore(combineReducers, initialState, compose(
                                              applyMiddleware(...middleware),
                                              window.__REDUX_DEVTOOLS_EXTENSION__ && window.__REDUX_DEVTOOLS_EXTENSION__()
                                          ));

                                          export default store;`

image This log from nextProps.user : Untitled

maeriens commented 3 years ago

Is this storybook related? It seems a problem with Redux. If it is, could you generate a repro based on this? It is hard to read code from a github issue, even if properly formatted.

sajjadshiasi commented 3 years ago

Is this storybook related? It seems a problem with Redux. If it is, could you generate a repro based on this? It is hard to read code from a github issue, even if properly formatted. The problem exactly with Redux. I can't access to props of redux

maeriens commented 3 years ago

But this is Storybook's issue list - is the issue related to storybook at all? Or is it exclusive to redux? I don't see any storybook code in what was posted. If it is, there are a few guides about how to create a story with data - one is here I know of a plugin for including redux but it is not official, can be found here Also, please consider doing a repro instead of pasting the code with these steps