Полное управление состоянием реакции

#reactjs

#reactjs

Вопрос:

Это не проблема, а скорее вопрос. Я хотел использовать React исключительно для своего глобального управления состоянием и передавать задачи через useReducer и useContext, и мне интересно, является ли это каким-либо образом правильным путем. Программист react сообщил мне, что таким образом компоненты перезаписываются, когда они не должны этого делать, но моя проверка элементов показывает только измененные перезапуски компонентов. Пожалуйста, укажите мне, могу ли я продолжать разработку таким образом или мне придется вернуться к Mobx или redux или многим другим сторонним библиотекам state manager.

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

1. Этот вопрос в первую очередь основан на мнении. Если комбинация контекста и глобального редуктора работает для вас, тогда дерзайте.

2. Redux разделяет состояние всего приложения, хранящегося в одном глобальном «хранилище». Это может быть полное управление состоянием в react. Согласно библиотекам управления состоянием react , Redux по-прежнему остается самой популярной библиотекой в 2023 году.

Ответ №1:

Да, вы можете, и это проще, чем когда-либо, благодаря новому API hooks! Для очень простых вещей, таких как, например, глобальная тема, вы можете просто создать контекст с помощью React.createContext и useContext.useContext.

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

 // AcmeContext.js

import React, { useReducer, createContext } from 'react'

const AcmeContext = createContext({})

const actions = {
  DO_SOMETHING: 'doSomething'
}

const actionCreators = dispatch => ({
  updateComment: comment => {
    dispatch({
      type: actions.DO_SOMETHING,
      payload: comment
    })
  }
})

// first paramter is your state, second is the action 
let reducer = (currentState, { type, payload }) => {
  switch (type) {
    case actions.DO_SOMETHING:
      // important: return a NEW new object for this context, don't change the old currentState
      return { ...currentState, hello: payload }
    default:
      return
  }
}

// this component wraps any of the child components that you want to share state with
function AcmeProvider({ children, initialState }) {
  const [state, dispatch] = useReducer(reducer, initialState)

  const actions = actionCreators(dispatch)

  return (
    <AcmeContext.Provider value={{ state, actions }}>
      {children}
    </AcmeContext.Provider>
  );
}

export { AcmeContext, AcmeProvider }
  

Затем вы оборачиваете компонент, которому хотите предоставить контекст, экспортированным поставщиком.

 // App.jsx

import { AcmeProvider } from './AcmeContext'
import TestComponent from './TestComponent'

render((
  <AcmeProvider initialState={{ hello: 'world' }}>
    <TestComponent />
  </AcmeProvider>
), document.querySelector('.app'))
  

Наконец, вы можете вызвать его из дочернего компонента.

 // TestComponent.jsx

import { AcmeContext } from './AcmeContext'

export default () => {
  const { state, actions } = useContext(AcmeContext)

  return (
    <div>
      Hello {state.hello}!

      <button onClick={() => actions.updateComment('me')}>Set response on onClick to 'me'</button>
    </div>
  )
}
  

У этого есть пара недостатков по сравнению с полной реализацией Redux. Вы не получаете инструментов Redux dev и не получаете таких вещей, как redux-thunk что означает, что вам придется добавить эту логику в компонент и заставить компонент обновлять контекст.

Ответ №2:

Да, вы можете полностью использовать API React по умолчанию для полного управления состоянием проекта. Введение перехватчиков упрощает управление. useContext постепенно стал моим любимым инструментом, потому что он устраняет необходимость в потребителях и делает JSX немного приятнее.

Если вы беспокоитесь о том, что вещи будут перезаписываться слишком много раз, вы все равно можете использовать все приемы в React Toolbox, такие как React.memo .