Как я могу получить состояние из селектора после обновления страницы?

#javascript #reactjs #redux #redux-saga #selectors-api

#javascript #reactjs #redux #redux-saga #селекторы-api

Вопрос:

У меня есть контейнерный компонент в шаблонном коде react JS, который получает данные (скажем, список школ) с использованием sagas в reducer и устанавливает состояние, которое будет считано функцией selector на моей странице рендеринга для отображения пользователю.

saga.js пример данных, возвращенных с сервера

     data: [  {
                id: '1',
                name: 'School1',
                location: 'Location1',
             },
             {
                id: '2',
                name: 'School2',
                location: 'Location2',
             },
          ]
  

actions.js фрагмент

     export function requestSchools() {
      return {
        type: REQUEST_SCHOOLS,
      };
    }
    export function requestSchoolsSucceeded(schoolsData) {
      return {
        type: REQUEST_SCHOOLS_SUCCEEDED,
        schoolsData,
      };
    }
  

reducer.js фрагмент

     function schoolsContainerReducer(state = initialState, action) 
    {
      switch (action.type) {
        case REQUEST_SCHOOLS_SUCCEEDED:
           return state.set('schools', action.schoolsData);
        default:
           return state;
      }
    }
  

selector.js фрагмент

     const makeSelectSchools = () =>
     createSelector(selectSchoolsContainerDomain, schoolState =>
     schoolState.get('schools'),
    );
  

index.js фрагмент

     //This will trigger action REQUEST_SCHOOLS in action.js
    constructor(props) {
        super(props);
        this.props.requestSchools();
    }

    render() {
        const { schools } = this.props;

        const renderSch = schools.data.map(sch => (
          <div key={sch.id}>
            {sch.name} {sch.location}
          </div>
        ));
        return (
          <div>
            {renderSch}
          </div>
        );
      }

    const mapStateToProps = createStructuredSelector({
      schoolsContainer: makeSelectSchoolsContainer(),
      schools: makeSelectSchools(),
    });

    function mapDispatchToProps(dispatch) {
      return {
        //dispatch request schools action
        requestSchools: () => dispatch(requestSchools()),
      };
    }
  

На первом этапе создания веб-пакета я могу получить данные и правильно их отобразить. Однако, когда я обновляю ту же страницу, данные поступают до редуктора (где задано состояние), но не в селектор (где я получаю состояние). Как я могу получить данные из редуктора в селектор после обновления страницы?

Ответ №1:

Прежде всего, постарайтесь не использовать метод componentWillMount, поскольку он устарел в React (https://reactjs.org/docs/react-component.html#unsafe_componentwillmount )

Я не понимаю, почему это не сработает при обновлении. Возможно, вам не нужен ваш селектор как функция, и, возможно, вам нужно значение по умолчанию для обеспечения достоверности сопоставления, которое вы выполняете в React (возможно, здесь проблема в этом?)

 const makeSelectSchools = createSelector(
  selectSchoolsContainerDomain, // What is this doing? Getting the state of the previous reducer right?
  schoolState => schoolState.get('schools') || [],
);
  

А затем вызвать его в контейнере:

 const mapStateToProps = createStructuredSelector({ schools: makeSelectSchools });
  

Вы уверены, что у вас больше нет журналов в вашей консоли? Или в инструментах разработки redux? Отлаживать его и так довольно сложно, и я лично не вижу никаких причин для того, чтобы ваше приложение работало только во время первой загрузки (если вы не управляете никаким кэшем).

Надеюсь, эти небольшие отзывы помогут вам сузить круг ваших проблем 🙂

Комментарии:

1. Спасибо за отзыв, и я сейчас не использую метод componentWillMount. Однако установка значения по умолчанию не решает проблему. В инструменте redux все действия, вызываемые в первом экземпляре (build), где все отображается, также вызываются при обновлении страницы (вручную). По моему мнению, проблема в selectors.js . Он не получает состояние из редуктора после перезагрузки страницы. Однако редуктор устанавливает состояние, и я могу его зарегистрировать. При получении состояния из селектора данные не определены.

2. Мне удалось решить проблему. Причина заключалась в том, что изначально я использовал набор данных в saga.js без выполнения запроса выборки на сервер api. После его изменения данные отображались при каждом обновлении страницы и работали нормально.