@Andriy022

Как формувать массив с обьектов в userReducer?

Мне нужно чтобы при клику на кнопку Save обьект запушивался в массив.Никак не получается.

import React, {useReducer} from 'react';

const renders = (animals, action) => {
    switch (action.type) {
        case 'xxx':
            return {...animals, [action.field]: action.payload}

        default:
            return animals
    }
}
const catAndDog = {
    cat: '', dog: ''
}
const Animals = () => {

    const [animals, dispatch] = useReducer(renders, catAndDog)

    const save = (e) => {
        dispatch({
            type: 'xxx',
            field: e.target.name,
            payload: e.target.value
        })
    }
    const animalCat = (e) => {
        e.preventDefault()
        console.log(animals)
    }
    const animalDog = (e) => {
        e.preventDefault()
        console.log(animals)
    }
    return (
        <div>
            <form onSubmit={animalCat}>
                <label>Cat:<input type="text" value={animals.cat} name={'cat'} onChange={save}/></label>
                <button>Save</button>
            </form>
            <form onSubmit={animalDog}>
                <label>Dog:<input type="text" value={animals.dog} name={'dog'} onChange={save}/></label>
                <button>Save</button>
            </form>
            <hr/>
        </div>
    );
};

export default Animals;
  • Вопрос задан
  • 87 просмотров
Решения вопроса 1
0xD34F
@0xD34F Куратор тега React
Добавляем в массив копию исходного объекта:

const defaultAnimals = {
  cat: '',
  dog: '',
  mouse: '',
  rhinoceros: '',
};

const animalsReducer = (state, action) => {
  switch (action.type) {
    case 'updateObj':
      return {
        ...state,
        obj: {
          ...state.obj,
          [action.payload.name]: action.payload.value,
        },
      };

    case 'addObjToArr':
      return {
        ...state,
        arr: [ ...state.arr, state.obj ],
        obj: defaultAnimals,
      };

    default:
      return state;
  }
};

const Animals = () => {
  const [ animals, dispatch ] = useReducer(animalsReducer, {
    obj: defaultAnimals,
    arr: [],
  });

  const onChange = ({ target: { name, value } }) => {
    dispatch({
      type: 'updateObj',
      payload: { name, value },
    });
  };
  
  const onSubmit = e => {
    e.preventDefault();
    dispatch({
      type: 'addObjToArr',
    });
  };

  return (
    <div>
      <form onSubmit={onSubmit}>
        {Object.entries(animals.obj).map(([ k, v ]) => (
          <div key={k}>
            <label>
              {k}:
              <input name={k} value={v} onChange={onChange} />
            </label>
          </div>
        ))}
        <button>Save</button>
      </form>
      <pre>{JSON.stringify(animals.obj, null, 2)}</pre>
      <pre>{JSON.stringify(animals.arr, null, 2)}</pre>
    </div>
  );
};

Или, добавляем в массив объект, содержащий значение только одного из свойств исходного объекта:

const animalsReducer = (state, action) => {
  switch (action.type) {
    case 'updateObj':
      return {
        ...state,
        obj: {
          ...state.obj,
          [action.payload.name]: action.payload.value,
        },
      };

    case 'addObjToArr':
      return {
        ...state,
        arr: [
          ...state.arr,
          {
            animal: action.payload,
            name: state.obj[action.payload],
          },
        ],
      };

    default:
      return state;
  }
};

const Animals = () => {
  const [ { obj, arr }, dispatch ] = useReducer(animalsReducer, {
    obj: {
      cat: '',
      dog: '',
      mouse: '',
      rhinoceros: '',
    },
    arr: [],
  });

  const onChange = ({ target: { name, value } }) => {
    dispatch({
      type: 'updateObj',
      payload: { name, value },
    });
  };
  
  const onSubmit = (e, animal) => {
    e.preventDefault();
    dispatch({
      type: 'addObjToArr',
      payload: animal,
    });
  };

  return (
    <div>
      {Object.entries(obj).map(([ k, v ]) => (
        <form onSubmit={e => onSubmit(e, k)} key={k}>
          {k}:
          <input name={k} value={v} onChange={onChange} />
          <button>Save</button>
        </form>
      ))}
      <pre>{JSON.stringify(obj, null, 2)}</pre>
      <pre>{JSON.stringify(arr, null, 2)}</pre>
    </div>
  );
};
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы