Хук useSelector сначала возвращает неопределенное состояние, а после вызова действия возвращает состояние правильно - PullRequest
0 голосов
/ 22 апреля 2020

Я новичок в использовании React-хуков и пытаюсь интегрировать свой проект с redux, дело в том, что в функциональном компоненте, который я использую для входа в систему, когда я пытаюсь получить свойства initialState с помощью useSelector, состояние не определено.

import React, {useState} from 'react';
import loginStyles from './login.module.css';
import {useDispatch , useSelector, shallowEqual} from 'react-redux';
import {login} from '../../store/actions/actions';

export default (props) =>  {

    const initialState = {
        "email":'',
        "password":''
    }
    const dispatch = useDispatch();

    const [loginForm, setValue] = useState(initialState);


    const changeValue = (event) => {
        const name = event.target.name;
        const value = event.target.value;
        setValue(prevState => {
            return {
                ...prevState,
                [name]: value
            }
        });

    }



    useSelector((state) => {
       console.log(state)
    });


    return (
        <article className={loginStyles.main}>
            <aside className={loginStyles.left}>

            </aside>
            <aside className={loginStyles.right}>
                <div>
                    <input name="email" onChange={(event) => changeValue(event) } type = "text" value = {loginForm['email']} />
                    <input name="password" onChange={(event) => changeValue(event) } type = "text" value = {loginForm['password']} />
                    <button onClick={() => dispatch(login("jared", true))} >clicl</button>
                </div>
            </aside>
        </article>
    );

}

После того, как я нажал кнопку, он печатает правильное состояние, но при первом рендере он печатает неопределенное. Так что я должен изменить?

Вот остальная часть моего кода. Спасибо.

Приложение. js


import React from 'react';
import {Provider} from 'react-redux';
import { createStore } from 'redux';
import reducer from './store/reducer';
import Layout from './layouts/main';
import './app.css';
function App() {

const store = createStore(reducer);

  return (
    <Provider store={store}>
      <Layout />
    </Provider>
  );
}

export default App;
import React from 'react';
import {Provider} from 'react-redux';
import { createStore } from 'redux';
import reducer from './store/reducer';
import Layout from './layouts/main';
import './app.css';
function App() {

const store = createStore(reducer);

  return (
    <Provider store={store}>
      <Layout />
    </Provider>
  );
}

export default App;
import React from 'react';
import {Provider} from 'react-redux';
import { createStore } from 'redux';
import reducer from './store/reducer';
import Layout from './layouts/main';
import './app.css';
function App() {

const store = createStore(reducer);

  return (
    <Provider store={store}>
      <Layout />
    </Provider>
  );
}

export default App;

редуктор. js

const initialState = {
    logged: false,
    user: null,
    empresas: null
}

const reducer = (state = initialState, action) => {
    switch(action.type) {
        case 'ONLOGIN': {
            return {
                ...state,
                user:action.user,
                logged: true
            }
        }
        case 'ONLOGOUT': {
            return {
                ...state, 
                user: null,
                logged: false
            }
        }
    }
}

export default reducer;

действия. js


const login = (user, logged)=> {
    return {
        type:'ONLOGIN',
        user: user,
        logged: true
    }

}


export {login}

Ответы [ 2 ]

1 голос
/ 22 апреля 2020

Для получения начального состояния необходимо получить состояние хранилища при первой загрузке.

действий. js

const fetchState = () => {
  return {type: 'FETCH_STATE'}
}

редуктор. js

const reducer = (state = initialState, action) => {
    switch(action.type) {
        case 'ONLOGIN': {
            return {
                ...state,
                user:action.user,
                logged: true
            }
        }
        case 'ONLOGOUT': {
            return {
                ...state, 
                user: null,
                logged: false
            }
        }
        case 'FETCH_STATE': {
            return {
                ...state, 
            }
        }
     default:
       return state;
    }
}

Наконец, в компоненте вам нужно получить состояние при первой загрузке с помощью React.useEffect или componentDidMount

import React, {useState} from 'react';
import loginStyles from './login.module.css';
import {useDispatch , useSelector, shallowEqual} from 'react-redux';
import {login} from '../../store/actions/actions';

export default (props) =>  {

    const initialState = {
        "email":'',
        "password":''
    }
    const dispatch = useDispatch();

    const [loginForm, setValue] = useState(initialState);

   React.useEffect(() => {
     dispatch(fetchState())
   },[])

    // remaining code
0 голосов
/ 22 апреля 2020

Приведенный выше код работает нормально. Я сам запускаю приведенный выше код и успешно получаю свойства initialState с помощью useSelector.

{logged: true, пользователь: "jared", empresas: null} logged: true пользователь: "jared" empresas: null.

Возможны проблемы в вашем проекте, такие как

  1. . Вы должны проверить, экспортировали ли вы правильную функцию редуктора.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...