How to listen redux state changes in react hooks?

Viewed 2625

I have multiple forms and buttons which user can edit now I would like to display a button save if the state of redux changes.

live demo : display button save when the state changes

Here is my redux.

const initialState = {
  firstName: "Kunta ",
  lastName: "Kinte",
  age: 35,
  country: "Ghana",
  color: "#000"
};

const DetailsReducer = (state = initialState, action) => {
  const { name, value } = action;

  return { ...state, [name]: value };
};

export default DetailsReducer;

Here is my js code to show save button if there is a change in redux state

    import React, { useState, useEffect } from "react";
    import { useSelector, useDispatch } from "react-redux";
    
    const Settings = () => {
      const fields = useSelector((state) => state);
      const dispatch = useDispatch();
      const [saveBtn, setSaveBtn] = useState(false);
    
      useEffect(() => {
        setSaveBtn(true); // show save btn if there is changes in state
      }, []);
    
      console.log(fields.firstName);
    
      return (
        <div>
          <div>
            <h1>Edit </h1>
            First Name:{" "}
            <input
              name="firstname"
              value={fields.firstName}
              onChange={(e) =>
                dispatch({ name: "firstName", value: e.target.value, type: "" })
              }
            />
            {saveBtn === true && <button className="btn-save">save </button>}
          </div>
        </div>
      );
    };
    
    export default Settings;


  [1]: https://codesandbox.io/s/multiple-inputs-kkm6l?file=/src/Components/Settings.js:0-816

What do I need to do to solve this problem.?

3 Answers

Did you try this ?

const fields = useSelector((state) => state.WHATEVER_REDUCER);

useEffect(() => {
    setSaveBtn(true); // show save btn if there is changes in state
}, [fields]);

You can try something like this:

<input
    name="firstname"
    value={fields.firstName}
    onChange={(e) =>
        dispatch({ name: "firstName", value: e.target.value, type: "" }, setSaveBtn(true))
    }
/>

While also removing:

useEffect(() => {
    setSaveBtn(true); // show save btn if there is changes in state
}, []);

You can do it like this. Remove effect hook, move setSaveBtn to input onChange and after you click save, just set setSaveBtn to false.

    import React, { useState, useEffect } from "react";
    import { useSelector, useDispatch } from "react-redux";
    
    const Settings = () => {
      const fields = useSelector((state) => state);
      const dispatch = useDispatch();
      const [saveBtn, setSaveBtn] = useState(false);
    
      console.log(fields.firstName);
    
      return (
        <div>
          <div>
            <h1>Edit </h1>
            First Name:{" "}
            <input
              name="firstname"
              value={fields.firstName}
              onChange={(e) => {
                dispatch({ name: "firstName", value: e.target.value, type: "" })
                setSaveBtn(true)
              }}
            />
            {saveBtn === true && 
              <button
               onClick={() => setSaveBtn(false)}
              className="btn-save">save </button>}
          </div>
        </div>
      );
    };
    
    export default Settings;
Related