d2207
d2207

Reputation: 79

How to get value from input?

I make simple task for getting job. Working with react and redux. When i get value from input and send them to reducer they are lost in the way. Wait, not so easy. 1st item getting by reducer gets prop name, age, type, index and return new state. Nice. But other items lost prop name and age in the way. What? How did them it? Reducer return empty obj for render. Dont look on obj in dispatch i will rework it.

REDUCER

case 'EDIT_ITEM':
            console.log(action.name, action.age, action.id);
            return state.map((item, index) =>
                action.id === index
                    ? {
                        name: action.name,
                        age: action.age
                    }
                    : item
            );

App.js

function EditUsers() {
        const listItems = users.map(function (value, index) {
            return (
                <form>
                    <div className="input-group">
                        <div className="input-group-prepend">
                            <span className="input-group-text">{value.name}, {value.age}</span>
                        </div>
                        <input type="text" placeholder="New name" id="newName" className="form-control"/>
                        <input type="text" placeholder="New age" id="newAge" className="form-control" aria-describedby="button-addon2"/>
                        <div className="input-group-append">
                            <button onClick={() => dispatch({
                                type: 'EDIT_ITEM',
                                id: index,
                                name: document.getElementById('newName').value,
                                age: document.getElementById("newAge").value
                            })}
                                    className="btn btn-outline-primary"
                                    type="button"
                                    id="button-addon2">
                                Изменить
                            </button>
                        </div>
                    </div>
                </form>
            )
        });
        return (
            <div>{listItems}</div>
        )
    }

Upvotes: 0

Views: 253

Answers (1)

Drew Reese
Drew Reese

Reputation: 203482

You won't be able to access the input values from the button's onClick event, but if you decide to leave the inputs uncontrolled and move the logic to the associated form's onSubmit callback, then you can access the form's field values from the onSubmit event.

Define a submitHandler function to consume both the index and submit event, e:

const submitHandler = index => e => {
  e.preventDefault(); // <-- prevent the default form action, important!
  const { newName, newAge } = e.target; // <-- destructure the inputs from the event target

  dispatch({
    type: "EDIT_ITEM",
    id: index,
    name: newName.value, // <-- extract the input value
    age: newAge.value // <-- extract the input value
  });
};

Here the path to the input value is e.target.<fieldId>.value. Notice I've also defined submitHandler to curry the index, which allows for more optimal usage when mapping elements.

Next, attach the submitHandler callback to the onSubmit prop of the form.

const listItems = users.map(function(value, index) {
  return (
    <form key={index} onSubmit={submitHandler(index)}>
      ...

Here the curried function submitHandler(index) takes the index and encloses it in an instance of the callback, returning a function that takes the onSubmit event object, e => {....

Finally, update the button to have type="submit" and no onClick handler.

<button
  className="btn btn-outline-primary"
  type="submit"
  id="button-addon2"
>
  Изменить
</button>

Full code

const submitHandler = index => e => {
  e.preventDefault();
  const { newName, newAge } = e.target;

  dispatch({
    type: "EDIT_ITEM",
    id: index,
    name: newName.value,
    age: newAge.value
  });
};

function EditUsers() {
  const listItems = users.map(function(value, index) {
    return (
      <form key={index} onSubmit={submitHandler(index)}>
        <div className="input-group">
          <div className="input-group-prepend">
            <span className="input-group-text">
              {value.name}, {value.age}
            </span>
          </div>
          <input
            type="text"
            placeholder="New name"
            id="newName"
            className="form-control"
          />
          <input
            type="text"
            placeholder="New age"
            id="newAge"
            className="form-control"
            aria-describedby="button-addon2"
          />
          <div className="input-group-append">
            <button
              className="btn btn-outline-primary"
              type="submit"
              id="button-addon2"
            >
              Изменить
            </button>
          </div>
        </div>
      </form>
    );
  });
  return <div>{listItems}</div>;
}

Edit Incontrolled Input Form Submit

Upvotes: 1

Related Questions