Home > Back-end >  Getting Text Input value with Redux in a React App
Getting Text Input value with Redux in a React App

Time:10-30

I want to create a small chat App, it has a message board, a text input and a button to send. I do this for React/Redux learning. I'm familiar with React and got the concept of Redux. But right now, I have problem and didn't find anything in my searches.

I want to catch and send text input data, when I press the send button. In pure react I bind the text input to a state via useState. Right now with Redux, I don't know what can I do. How can I pass the text input value to a specific action? What I need is very simple, catch text input value. But I can't find any resources for this. I'm not looking for things like Form or submitting a form, there s no submitting data to server etc, just getting the input value. I don't know if it's possible to pass any argument to Redux actions to store them?

I cant find any tutorial or resources. Any help will be appreciated.

CodePudding user response:

You can dispatch an action that accepts the input value when the submit button is pressed. You can then perform the required actions on the captured value in your redux reducer.
Dispatch an action from your component.

import React, {useRef} from 'react'
import {useDispatch} from 'react-redux'

export default function App(){
   const textVal = useRef()
   const dispatch = useDispatch()
   function sendTextValueHandler(){
       const inputVal = textVal.current.value
       dispatch({type:'INP_VAL', message: inputVal}) //Pass input value to redux store
   } 
   return(
       <input type='text' ref={textVal}/>
       <button onClick={sendTextValueHandler}>Send</button>
   )
}

In your redux store,

const reducer = (state={message:''},action)=>{
   if(action.type === 'INP_VAL'){
     const inputValue = action.message //Capture the input value and do the required operation.
    return {...state,message:inputValue}
   }
   .
   .
   .
   return state
}

const store = useStore(reducer)
export default store

The above snippets are basic structural examples of how you can accomplish this task. Once you get the gist of it, you can further migrate to using redux-toolkit which offers more flexibility and better code segmentation.

CodePudding user response:

Before adding redux, a simple solution with an internal state looks like this:

import React, {useState} from 'react'

const Sample = () => {
  const [inputValue, setInputValue] = useState("");
  
  const handleChange = (e) => {
     setInputValue(e.target.value)
  }

  return(
    <input type='text' value={inputValue} onChange={handleChange} />
  )
}

Now, try it with redux implementation:

import React from 'react';
import {useDispatch, useSelector} from 'react-redux';

const Sample = () => {
  const dispatch = useDispatch();
  const inputValue = useSelector(state => state.sample.value)
  
  const handleChange = (e) => {
    dispatch({type: 'CHANGE_INPUT_VALUE`, payload: e.target.value})
  }

  return(
    <input type='text' value={inputValue} onChange={handleChange}>
  )
}

the reducer might look like this:

const initialState = {
  value: "";
}

const sampleReducer = (state=initialState, action) => {
  switch(action.type){
    case 'CHANGE_INPUT_VALUE':
      return{
        ...state,
        value: action.payload
      }
    // other cases ...
    default: 
     return state
  }
}

I rather to define actions and selector in separated files and import them where they need:

Sample action file:

export const CHAGNE_INPUT_VALUE = 'CHANGE_INPUT_VALUE';

export const changeInputValue = (value) => ({type: CHAGNE_INPUT_VALUE, payload: value})

Sample selector file:

export const selectInputValue = (state) => state.sample.value

Now apply them to the Sample component:

import React from 'react';
import {useDispatch, useSelector} from 'react-redux';

import {changeInputValue} from 'path/to/action/file';
import {selectInputValue} from 'path/to/selector/file';

const Sample = () => {
  const dispatch = useDispatch();
  const inputValue = useSelector(selectInputValue)

  const handleChange = (e) => {
    dispatch(changeInputValue(e.target.value))
  }

  return(
    <input type='text' value={inputValue} onChange={handleChange}>
  )
}

Now, back to the question: Yes, you could add anything as a payload to the reducer, for example:

dispatch(updateUserProfile({name: "", age: 0, image: "", children: [], ...}))
case UPDATE_PROFILE:
   return {
     ...state,
     name: action.payload.name,
     age: action.payload.age,
   }

CodePudding user response:

there is onChange method in react for the inputs. and there is library called redux thunk to perform some extra logic to the action and pass some arguments.

please elaborate your question if the answer does not suffice

  • Related