Отправка действия из компонента с данными из дочернего компонента - PullRequest
0 голосов
/ 13 января 2020

Итак, я создаю небольшое приложение, чтобы выучить некоторый редукс / реакцию. Приложение включает в себя форму, созданную как компонент с кнопкой «Сохранить» (и некоторым другим нерелевантным кодом), и дочерний компонент, включающий поля формы.

Мое намерение состоит в том, чтобы обновить состояние приложения, которое обрабатывается redux, отправляя действие «SAVE» (из родительского компонента) при нажатии кнопки «сохранить», отправляя в качестве полезной нагрузки данные из полей внутри дочернего компонента.

Есть ли способ сделать это дружественным к реакции?

1 Ответ

1 голос
/ 13 января 2020

Если некоторая часть глобального состояния совместно используется несколькими компонентами, обернутыми общим (родительским) компонентом, вы можете попытаться:

  • связать обработчики событий дочерних компонентов с обратными вызовами родительского компонента
  • хранить изменения дочерних компонентов в локальном состоянии родителя
  • диспетчеризация SAVE действие по обновлению глобального состояния

Краткое демонстрационное описание ниже:

//dependencies
const { useState } = React,
      { render } = ReactDOM,
      { createStore } = Redux,
      { useDispatch, useSelector, Provider } = ReactRedux
      
//action, initial state, reducer, store
const SAVE_FEEDBACK = 'SAVE_FEEDBACK',
      initialState = {scores:[]},
      appReducer = (state=initialState, action) => {
        switch(action.type){
          case SAVE_FEEDBACK : {
            const {scores} = state,
                  {score} = action
            return {...state, scores:[...scores, score]}
          }
          default: return state
        }
      },
      store = createStore(appReducer)
      
//form component
const ScoreForm = ({onScoreInput, onNameInput}) => (
  <form>
    <select onChange={e => onScoreInput(e.target.value)}>
      <option value="" selected></option>
      <option value="awfull">awfull</option>
      <option value="awsome">awsome</option>
    </select>
    <input onKeyUp={e => onNameInput(e.target.value)} />
  </form>
)

//parent component
const MovieScore = () => {
  const [userScore, setScore] = useState(''),
        [userName, setName] = useState(''),
        dispatch = useDispatch(),
        userScores = useSelector(({scores}) => scores),
        handleScoreInput = score => setScore(score),
        handleNameInput = name => setName(name),
        onSave = () => dispatch({type: SAVE_FEEDBACK, score: {userName, userScore}})
  return (
    <div>
      <img 
        src="https://upload.wikimedia.org/wikipedia/uk/a/a4/Knockin.jpg" 
        style={{maxHeight:200}}
      />
      <ScoreForm 
        onScoreInput={handleScoreInput}
        onNameInput={handleNameInput}
       />
      <button onClick={onSave}>Save</button>
      <div>
        {userScores.map(({userScore,userName}) => <div>{userName} thinks, this movie is {userScore}</div>)}
      </div>
    </div>
  )
}

//wrap into Provider component
render (
  <Provider {...{store}}>
    <MovieScore />
  </Provider>,
  document.getElementById('root')
)
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.12.0/umd/react.production.min.js"></script><script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.11.0/umd/react-dom.production.min.js"></script><script src="https://cdnjs.cloudflare.com/ajax/libs/redux/4.0.5/redux.min.js"></script><script src="https://cdnjs.cloudflare.com/ajax/libs/react-redux/7.1.3/react-redux.min.js"></script><div id="root"></div>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...