最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Passing multiple props and actions in reactredux - Stack Overflow

programmeradmin0浏览0评论

I'm using React and Redux in my web app.
In the login page, I have multiple fields (inputs).
The login page in posed from multiple ponents to pass the props to.

I was wondering how should I pass the props and update actions.
For example, lets assume I have 5 inputs in my login page.

LoginPage (container) -> AuthenticationForm (Component) -> SignupForm (Component)

In the LoginPage I map the state and dispatch to props,
and I see 2 options here:

mapStateToProps = (state) => ({
  input1: state.input1,
  ...
  input5: state.input5
})

mapDispatchToProps = (dispatch) => ({
  changeInput1: (ev) => dispatch(updateInput1(ev.target.value))
  ...
  changeInput5: (ev) => dispatch(updateInput5(ev.target.value))
})

In this solution, I need to pass a lot of props down the path (the dispatch actions and the state data).

Another way to do it is like this:

mapStateToProps = (state) => ({
  values: {input1: state.input1, ..., input5: state.input5}
})

mapDispatchToProps = (dispatch) => ({
  update: (name) => (ev) => dispatch(update(name, ev.target.value))
})

In this solution, I have to keep track and send the input name I want to update.

How should I engage this problem?
It seems like fundamental question, since a lot of forms have to handle it,
but I couldn't decide yet what would suit me now and for the long run.

What are the best practices?

I'm using React and Redux in my web app.
In the login page, I have multiple fields (inputs).
The login page in posed from multiple ponents to pass the props to.

I was wondering how should I pass the props and update actions.
For example, lets assume I have 5 inputs in my login page.

LoginPage (container) -> AuthenticationForm (Component) -> SignupForm (Component)

In the LoginPage I map the state and dispatch to props,
and I see 2 options here:

mapStateToProps = (state) => ({
  input1: state.input1,
  ...
  input5: state.input5
})

mapDispatchToProps = (dispatch) => ({
  changeInput1: (ev) => dispatch(updateInput1(ev.target.value))
  ...
  changeInput5: (ev) => dispatch(updateInput5(ev.target.value))
})

In this solution, I need to pass a lot of props down the path (the dispatch actions and the state data).

Another way to do it is like this:

mapStateToProps = (state) => ({
  values: {input1: state.input1, ..., input5: state.input5}
})

mapDispatchToProps = (dispatch) => ({
  update: (name) => (ev) => dispatch(update(name, ev.target.value))
})

In this solution, I have to keep track and send the input name I want to update.

How should I engage this problem?
It seems like fundamental question, since a lot of forms have to handle it,
but I couldn't decide yet what would suit me now and for the long run.

What are the best practices?

Share Improve this question asked Sep 8, 2018 at 17:23 itaieditaied 7,10713 gold badges58 silver badges94 bronze badges
Add a ment  | 

3 Answers 3

Reset to default 5

I think best practice would be to handle all of this logic in the React ponent itself. You can use ponent's state to store input's data and use class methods to handle it. There is good explanation in React docs https://reactjs/docs/forms.html

You probably should pass data in Redux on submit. Ether storing whole state of the form as an object, or not store at all and just dispatching action with api call.

TL;DR. it's a more 'general' coding practice. But let's put it under a react-redux context.

Say if you go with your first approach, then you will probably have 5 actionCreators as:

function updateInput1({value}) {  return {type: 'UPDATE_INPUT1', payload: {value}} }
...
function updateInput5({value}) {  return {type: 'UPDATE_INPUT5', payload: {value}} }

Also if you have actionTypes, then:

const UPDATE_INPUT1 = 'UPDATE_INPUT1'
...
const UPDATE_INPUT5 = 'UPDATE_INPUT5'

The reducer will probably look like:

function handleInputUpdate(state = {}, {type, payload: {value}}) {
  switch (type) {
    case UPDATE_INPUT1: return {..., input1: value}
    ...
    case UPDATE_INPUT5: return {..., input5: value}
    default: return state
  }
}

What's the problem? I don't think you're spreading too many props in mapStateToProps/mapDispatchToProps, Don't repeat yourself!

So naturally, you want a more generic function to avoid that:

const UPDATE_INPUT = 'UPDATE_INPUT'

function updateInput({name, value}) { return {type: UPDATE_INPUT, payload: {name, value}} }

function handleInputUpdate(state = {inputs: null}, {type, payload: {name, value}}) {
  switch (type) {
    case UPDATE_INPUT: return {inputs: {...state.inputs, [name]: value}}
    default: return state
  }
}

Finally, the "selector" part, based upon how the state was designed, get ponent's props from it would be fairly trivial:

function mapStateToProps(state) { return {inputs: state.inputs} }
function mapDispatchToProps(dispatch) { return {update(name, value) { dispatch(updateInput(name, value)) } }

In summary, it's not necessarily a redux/react problem, it's more how you design app state, redux just offers you utilities and poses some constraints to enable "time traveling" (state transitions are made explicit within a mutation handler based on a separate action).

Best practice to handle this problem is having a local state on your Form Component and managing it locally because I believe it's not a shared state. onSubmit you could dispatch your action passing down the state to the action which is required in making an API call or posting it to your server.

If you try to keep updating your store as the user types, it will keep dispatching the action which might cause problems in future. You read more here Handling multiple form inputs in react

发布评论

评论列表(0)

  1. 暂无评论