Dawn17
Dawn17

Reputation: 8297

Updating states from input field when using React-Redux

I am currently using React-Redux but for a pretty simple app. The app just simply takes a user ID, password, and an address of a server that the user wants to get into. It gets into the server and runs a script in the server. But the functionality of the app is not important in my question.

I only need 3 states (username, password, and server_address) for the app.

However, I have three different reducers and actions that do the same thing just with the different state.

For example,

userReducer.js

// reducer functions takes a default state and an action to apply

import { UPDATE_USER } from '../actions/userActions'

export default function userReducer(state = '', { type, payload }) {
    switch (type) {
        case UPDATE_USER:
            return payload;
        default:
            return state;
    }
}

passwordReducer.js

// reducer functions takes a default state and an action to apply

import { UPDATE_PASSWORD } from '../actions/passwordActions'

export default function passwordReducer(state = '', { type, payload }) {
    switch (type) {
        case UPDATE_PASSWORD:
            return payload;
        default:
            return state;
    }
}

routerReducer.js // this is the server

// reducer functions takes a default state and an action to apply

import { UPDATE_ROUTER } from '../actions/routerActions'

export default function routerReducer(state = '', { type, payload }) {
    switch (type) {
        case UPDATE_ROUTER:
            return payload;
        default:
            return state;
    }
}

and actions that look like this:

export const UPDATE_PASSWORD = 'updatePassword'

export function updatePassword(newPassword) {
    return {
        type: UPDATE_PASSWORD,
        payload: {
            'newPassword': newPassword
        }
    }
}

It's same for the other two with the different variable.

Then in my component, I just connected mapActionsToProps to the component and put 3 functions that does the same thing (updating the state)

class Container extends React.Component {
    constructor(props) {
        super(props)
    }
    onUpdateUser = (e) => {
        this.props.onUpdateUser(e.target.value)
    }

    onUpdatePassword = (e) => {
        this.props.onUpdatePassword(e.target.value)
    }

    onUpdateRouter = (e) => {
        this.props.onUpdateRouter(e.target.value)
    }
    ...

using it like

This kinda works, but I am not sure if this is the right way to use React-Redux. First of all, they are duplicates and do not seem like a good practice. However, I can't think of a way to update each state in a React-Redux way without just putting similar codes.

Any help?

Upvotes: 0

Views: 1592

Answers (2)

joseluismurillorios
joseluismurillorios

Reputation: 1014

You can use a single function just to send the key/value pairs you want to update.

export const UPDATE_USER_VALUE = 'updateUserValues'

export function updateUser(payload) {
    return {
        type: UPDATE_USER_VALUE,
        payload: payload,
    }
}

You must call that function like this:

onUpdateUser = (e) => {
  this.props.onUpdateUser({
    key: 'name',
    value: e.target.value
  })
}

onUpdatePassword = (e) => {
  this.props.onUpdateUser({
    key: 'password',
    value: e.target.value
  })
}

Then just update the values.

import { UPDATE_USER_VALUE } from '../actions/userActions'

const defaultState = {
  username = '',
  password = '',
  server_address = ''
};

export default function passwordReducer(state = defaultState, { type, payload }) {
    switch (type) {
        case UPDATE_USER_VALUE:
            return {
               ...state,
               state[payload.key]: payload.value
            };
        default:
            return state;
    }
}

Upvotes: 0

Rasuna Khatami
Rasuna Khatami

Reputation: 1071

You could pass the event to your action.js

export const onInputChange = event => ({
  type: 'UPDATE_INPUT',
  payload: event
});

And simply grab the name and the value of the event in your reducer.js

const INITIAL_STATE = {
  user: '',
  password: ''
}

export const inputReducer = (state = INITIAL_STATE, action) => {
  switch (action.type) {
    case: 'UPDATE_INPUT':
      return { ...state, [action.payload.target.name]: action.payload.target.value };
    default:
      return state;
  };
};

Then in your component

// ...
handleChange(event) {
  this.props.onInputChange(event);
};

// ...
<input type='text' name='user' onChange={this.handleChange} />

Upvotes: 1

Related Questions