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

    @ssdakj Автор вопроса
    Спасибо большое за подробный ответ, в принцепи я пришел к схожей логике, только по максимум переиспользую код там где это возможно , так как у меня есть action (thunk) fetchProduct для страницы продукта , его же и использую я в редактирование , а уже в нем проверяю если продукт есть в store то проверяю по id , короче вот мой окончательный код, может кому будет интересно:

    Reducer:
    const initialState = {
      products: [],
      product: null,
      loading: false,
      sending: false,
      error: null
    };
    
    const reducer = (state = initialState, action) => {
      switch (action.type) {
        case 'FETCH_PRODUCTS_REQUEST':
        case 'FETCH_PRODUCT_REQUEST':
          return { ...state, loading: true };
    
        case 'UPDATE_PRODUCT_REQUEST':
          return { ...state, sending: true };
    
        case 'FETCH_PRODUCTS_SUCCESS':
          return { ...state, loading: false, error: null, products: action.payload };
    
        case 'FETCH_PRODUCT_SUCCESS':
          return { ...state, loading: false, error: null, product: action.payload };
    
        case 'UPDATE_PRODUCT_SUCCESS':
          return { ...state, sending: false, error: null, product: action.payload };
    
        case 'FETCH_PRODUCTS_FAILURE':
        case 'FETCH_PRODUCT_FAILURE':
          return { ...state, loading: false, error: action.payload };
    
        case 'UPDATE_PRODUCT_FAILURE':
          return { ...state, sending: false, error: action.payload };
    
        default:
          return state;
      }
    };


    Thunks:
    const fetchProduct = id => async (dispatch, getState) => {
      const { product } = getState().products;
      if (product?.id === id) return;
    
      dispatch(fetchProductRequest());
      try {
        const response = await axios.get(`/products/${id}`);
        dispatch(fetchProductSuccess(response.data.product));
      } catch (error) {
        dispatch(fetchProductFailure(error.response.data));
      }
    };
    
    const updateProduct = fields => (dispatch, getState) => {
      return new Promise(async resolve => {
        const { product } = getState().products;
    
        dispatch(updateProductRequest());
        try {
          const response = await axios.post(`/products/${product.id}`, fields);
          dispatch(updateProductSuccess(response.data.product));
          resolve();
        } catch (error) {
          dispatch(updateProductFailure(error.response.data));
        }
      });
    };


    Component:
    const ProductEdit = () => {
      const [fields, setFields] = useState({
        name: '',
        text: '',
        price: ''
      });
    
      const { product } = useSelector(state => state.products);
    
      const params = useParams();
      const dispatch = useDispatch();
      const history = useHistory();
    
      useEffect(() => {
        dispatch(fetchProduct(params.id));
      }, [dispatch, params.id]);
    
      useEffect(() => {
        if (product) {
          setFields(product);
        }
      }, [product]);
    
      const onChange = ({ target: { name, value } }) => {
        setFields(fields => ({ ...fields, [name]: value }));
      };
    
      const onSubmit = event => {
        event.preventDefault();
        dispatch(updateProduct(fields)).then(() => history.push(`/products/${params.id}`));
      };
    
      return (
        <form onSubmit={onSubmit}>
          <input type='text' name='name' value={fields.name} onChange={onChange} />
          <input type='text' name='text' value={fields.text} onChange={onChange} />
          <input type='text' name='price' value={fields.price} onChange={onChange} />
          <button>create product</button>
        </form>
      );
    };
  • Как прокинуть данные полученные с сервера в форму редактирования?

    @ssdakj Автор вопроса
    paoluccio, То что пришло в голову , это в store при старте product сделать null , а в компоненте создать ещё один useEffect в котором проверить если product !== null тогда закинуть его в локальный state , тогда должно все правильно работать , но на сколько это правильный вариант не знаю , вообще в документациях не видел чего то похожего, как вообще люди редактируют данные с store
  • Как прокинуть данные полученные с сервера в форму редактирования?

    @ssdakj Автор вопроса
    paoluccio, Нет, у меня один reducer , для всего что связано с products ( список , один , редактирование, добавление, удаление )

    Если подробно то:
    Получаем продукт с backend помещаем в store , потом берём со store помещаем в локальный стейт , дальше редактируем то что в локальном , при submit отравляем на сервер то что в локальном стейте , после backend возвращает или обновлённый продукт или ошибку , если все ок то тогда можем перезаписать уже продукт который в store

    По идеи как то так это должно работать, так как если бы мы меняли просто продукт в самом store и произошла бы ошибка , тогда бы было то, что в бд не соответствует тому, что в store и тогда по новой нужно запрашивать продукт, хотя он даже никак не изменился в бд
  • Как прокинуть данные полученные с сервера в форму редактирования?

    @ssdakj Автор вопроса
    paoluccio, Да вы правильно понимаете , но делается это для того чтобы при перезагрузки страницы мы все также видели форму редактирования продукта , а не пустую форму , а вот в самом fetchProduct уже можно проверить , если продукт этот уже есть в store то можно его не запрашивать, но опять же зависит от ситуации, если данные очень часто меняются разными людьми наверно целесобразно всегда получать актуальные данные
  • Как прокинуть данные полученные с сервера в форму редактирования?

    @ssdakj Автор вопроса
    1 и 2 ) На проекте всеравно используется redux для других вещей , поэтому особо нету разницы где хранить бизнес логику + тестировать redux на много удобнее чем компоненты, но в данном случае также можно применить проверку , если мы переходим со страницы продукта, на страницу редактирования этого продукта то нам не нужно запрашивать данные снова, или другой пример, есть у нас список продуктов с номером страницы (currentPage), если вы перейдете на страницу продукта и снова вернетесь, то в таком случае вы можете посмотреть на какой странице последний раз были и вернуться на нее , а при локальном стейте будете каждый раз возвращаться на первую и тд.

    3) так правильно, если включить eslint то увидите предупреждение , а если стоит автокомплит , то он сам исправит и добавит dispatch туда

    4.) написал в 1 и 2 пункте

    А сама суть вопроса осталась прежняя, есть product полученный с сервера в store, есть страница редактирвоания продукта , есть локальный стейт для формы (чтобы не изменять продукт в самом store пока сервер не вернет что все успешно ошибок нету сервер принял) , так как сервер может вернуть и ошибку , а мы уже изменили в store продукт, тогда нам останется только опять его запрашивать, но это звучит не очень , поэтому как мне кажется нужно в локальный state (fields) закинуть product , этот product появится в форме мы его отредактируем , отправим этим данные (fields) на сервер , сервер скажет все ок , тогда мы смело можем обновить в store продукт , потом сделать редирект на страницу этого продукта , а он уже у нас есть в store и мы можем не запрашивать его снова.

    Может если пойти от обратного будет понятнее чего я добиваюсь, я не хочу делать onChange для продукта который в самом store, типо onChange = ({ target: { name, value } }) => dispatch(setProductField(name, value)) ... так как я описывал выше , это привет к тому что если сервер вернет ошибку , то мне придется заново запрашивать продукт , так как в store продукт я обновил но в базе осталось все по прежнему

    Думаю что как-то так это работает по логике
  • Как прокинуть данные полученные с сервера в форму редактирования?

    @ssdakj Автор вопроса
    1. по мимо страницы редактирования , у меня также есть страница показа продукта, поэтому этот же экшен (thunk) получения продукта я использую и на странице редактиврования.
    2. То что написал выше + чтобы не изменять данные продукта в store, тоесть задумка была скопировать данные из store в локальный , изменить эти данные, отправить на сервер , и только если сервер возращает success тогда уже перезаписать в store
    3. Не понял вопроса
    4. Конкретно вопрос в то как скопировать полученный с сервера продукт из store, положить его в локальный стейт, чтобы отредактировать не затрагивая данные в самом store, так как сервер может не принять эти данные и тогда мне нужно сбросить то что я изменил, а если я изменю в самом store , то сбросить я не смогу , и придется запрашивать по новой