ReactJs - инициализировать Redux Store из параметров запроса URL - PullRequest
2 голосов
/ 23 октября 2019

Я чрезвычайно новичок в ReactJs и Redux. Я могу настроить простое приложение с несколькими компонентами React, отправляющими действия в хранилище Redux по нажатию кнопок, выбору выпадающего меню и т. Д. Но я не могу понять, что могу сказать, как бы вы выполнили инициализацию состояния приложенияна основе параметра URL?

Например, допустим, у вас есть страница профиля пользователя, и в зависимости от параметра URL «userid» вы хотите отображать различные пользовательские данные на странице при первой загрузке. Сначала я подумал о том, чтобы использовать метод жизненного цикла componentDidMount и отправить действие в хранилище - возможно, что-то вроде «loadUser (userid)». Но это похоже на излишество - существует ли общепринятый способ наполнения магазина какой-либо начальной ценностью?

Ответы [ 4 ]

1 голос
/ 23 октября 2019

Если вам нужны переменные, специфичные для маршрута, то, вероятно, проще всего (и рекомендуется) использовать параметры маршрута для инициализации состояния и повторного выполнения действий.

Если вы используете компоненты на основе классов, loadUser(userId) должно быть в componentDidMount и componentDidUpdate.

Для функциональных компонентов вместо этого есть React hook useEffect () (который, кажется,стать лучшей / лучшей практикой в ​​эти дни).

Например:

Если вы используете response-router-dom в вашем файле rout.js / app.js, у вас будет маршрут, такой как:

<Route path='/some/path/:userid' component={someComponent}/>

Затем используйте props.match.params и используйте useEffect с идентификатором пользователя в качестве зависимости:

import React , {useEffect} from 'react'
import {connect} from 'react-redux'
import * as actions from 'path/to/redux/actions'

// destructure `match.params.userid`, redux `user` and redux action `loadUser` from props
const someComponent = ({ match:{params:{userid}} , user ,  loadUser}) => {

    useEffect(()=>{
      userid && loadUser(userid)
    },[loadUser , userid]) // runs after first mount and every time userid changes

    return <div>{user && user.id}</div>
}

connect(
    ({user})=>({user}),
    actions
)(someComponent)
0 голосов
/ 23 октября 2019

Я думаю, что вы можете использовать компоненты Switch и Route , где вы можете выбрать URL и параметры, которые будут переданы компоненту. Как только вы закончите с этим, вы можете решить в самом компоненте обновить состояние в хранилище.

Но для инициализации хранилища вы можете передать общее состояние, то есть пустой объект состояния или состояние вашей домашней страницы.

Надеюсь, это поможет !!

0 голосов
/ 23 октября 2019

В этом примере используется import { Record } from immutable для сохранения исходного состояния. Если вы хотите обновить это из строки запроса, то вы бы вызвали действие для обновления состояния, как и все остальное. Я бы назвал действие в конструкторе или componentDidMount().

  /*
  *
  * CourseContainer reducer
  *
  */

  import { Record } from 'immutable';
  import {
     FETCH_COURSE_FROM_QUERYSTRING,
     FETCH_COURSE_FROM_QUERYSTRING_SUCCESS
  } from './constants';

  const CourseContainerRecord = Record({
     course: {
        CourseTitle: '',
        AhecId: '',
        SeatsRemaining: 0,
        Price: 0,
        Hidden: true,
        Canceled: false,
        Objectives: '',
        CreditHours: '',
        Description: '',
     },
     coordinators: [],
  });

  export const initialState = new CourseContainerRecord({});

  function courseContainerReducer(state = initialState, action) {
     switch (action.type) {
        case FETCH_COURSE_FROM_QUERYSTRING_SUCCESS:
        // ... code
        default:
           return state;
     }
  }

  export default courseContainerReducer;

  /*
  *
  * CourseContainer actions
  *
  */
  import toastr from 'toastr';

  import {
     FETCH_COURSE_FROM_QUERYSTRING,
     FETCH_COURSE_FROM_QUERYSTRING_SUCCESS,
  } from './constants';

  // #region GET course
  export function fetchCourseFromQuerystring(courseId) {
     return {
        type: FETCH_COURSE_FROM_QUERYSTRING,
        courseId,
     };
  }

  export function fetchCourseFromQuerystringSuccess(course) {
     return {
        type: FETCH_COURSE_FROM_QUERYSTRING_SUCCESS,
        course,
     };
  }

РЕДАКТИРОВАТЬ Я могу добавить пример диспетчеризации, если он вам нужен.

0 голосов
/ 23 октября 2019

, поэтому сначала в своем компоненте контейнера (на любой странице / маршруте) вы можете получить строку запроса из URL-адреса и соответствующим образом обновить состояние приращения

Пример:

import queryString from 'querystring';

const App (props){

//semulate the component did mount behavior 
useEffect(()=>{
     const {
     active_section,
     tab,
    //or what ever
    } = queryString.parse(history.location.search.replace('?', ''));

  props.updateStore({
    active_section,
    tab
   })
},[])

export default connect(App)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...