Ответы пользователя по тегу Redux
  • Как прокинуть данные полученные с сервера в форму редактирования?

    @paoluccio
    Думаю, что опираться на три точки(список продуктов, один продукт, еще и локальный стейт для редактируемого продукта) с идентичными данными крайне излишне, т.к. создаётся путаница с синхронизацией. Считаю, что нужно опираться только на список продуктов из редакса и доставать из него нужные данные через селекторы. Для редактирования можно использовать временный локальный стейт, который при желании можно сбросить и вернуться к исходным данным.

    Имена немного изменил, чтобы было более понятно. Но вы, если что, спрашивайте, постараюсь помочь.

    // Component
    const ProductEdit = () => {
      const [editableData, setEditableData] = useState({});
    
      const { id } = useParams();
      // пытаемся достать продукт по id из списка
      const selectedProduct = useSelector(state => (
        state.products.find(product => product.id === id)
      ));
    
      useEffect(() => {
        // если продукт был найден, сразу заносим его в локальный стейт
        if (selectedProduct) {
          setEditableData(selectedProduct);
        }
        // иначе получаем данные с бэкэнда(минуя редакс) и затем заносим в локальный стейт
        // этот кейс будет срабатывать в случае если страница была перезагружена
        else {
          API.fetchProductById(id).then(fetchedProduct => setEditableData(fetchedProduct));
        }
      }, [selectedProduct, id]);
    
      const onChange = ({ target: { name, value } }) => {
        setEditableData(currentData => ({ ...currentData, [name]: value }));
      };
    
      const dispatch = useDispatch();
      const onSubmit = e => {
        e.preventDefault();
        dispatch(updateProduct({ id, ...editableData }));
      };
    
      return (
        <form onSubmit={onSubmit}>
          <input type='text' name='name' value={editableData.name || ''} onChange={onChange} />
          <input type='text' name='text' value={editableData.text || ''} onChange={onChange} />
          <input type='text' name='price' value={editableData.price || ''} onChange={onChange} />
          <button>update product</button>
        </form>
      );
    };

    // Thunk
    const updateProduct = product => async (dispatch, getState) => {
      try {
        await API.updateProduct(product);
        // проверяем на наличие списка продуктов, может не быть если страница перезагружалась
        if (getState().products.length) {
          dispatch(mergeUpdatedProduct(product));
          // ловим type этого экшна в редьюсере и перезаписываем старый продукт в списке
        }
        // если же список пустой, то при возврате на страницу показа продуктов заново получаем все данные
        // к тому моменту обновлённый продукт уже успешно будет проживать в бд
      } catch (error) {
        // не удалось обновить продукт
      }
    };
    Ответ написан
  • Как передать данные между двумя компонентами React (не родителем и потомком)?

    @paoluccio
    Можно попробовать динамически вставлять index в путь для Link:
    <Link to={`/edit/${index}`}>Edit</Link>

    Роут тоже слегка изменить:
    <Route path='/edit/:index'>
      <EditPage />
    </Route>


    Затем, на странице редактирования todo, index можно получить через хук useParams:
    import { useParams } from 'react-router-dom';
    
    const EditPage = () => {
      const { index } = useParams();
    
      // ...
    };
    Ответ написан