Хук useState теряет данные карты при обновлении страницы

Я использую хук useState для формы добавления продукта. Когда я обновляю свою страницу, данные для категории поля не отображаются (я пытаюсь отобразить категории, чтобы пользователь мог выбрать категорию из списка, чтобы создать продукт для этой категории). Но! Хранение данных в хранилище redux: введите описание изображения здесь Оно отображается только тогда, когда я перехожу к другому страницу с помощью response router (), а затем вернитесь назад.

Это мой код:

export const AddProduct = () => {
    const dispatch = useDispatch();
    const userId = useSelector(state => state.auth.userId);
    const categories = useSelector(state => state.categories.categories);
    const [avatar, setAvatar] = React.useState('');

    React.useEffect(() => {
        dispatch(categoriesActions.fetchCategories());
    }, [dispatch]);

    const [orderForm, setOrderForm] = React.useState({
        title: {
            elementType: 'input',
            label: 'Title',
            elementConfig: {
                type: 'text',
                placeholder: 'Title'
            },
            value: '',
            validation: {
                required: true
            },
            valid: false,
            touched: false
        },
        price: {
            elementType: 'input',
            label: 'Price',
            elementConfig: {
                type: 'text',
                placeholder: 'Price'
            },
            value: '',
            validation: {
                required: true
            },
            valid: false,
            touched: false
        },

        description: {
            elementType: 'textarea',
            label: 'Description',
            elementConfig: {
                type: 'text',
                placeholder: 'Description'
            },
            value: '',
            validation: {
                required: true
            },
            valid: false,
            touched: false
        },
        category: {
            elementType: 'select',
            label: 'Select category',

            elementConfig:
                categories.map(category => (
                    <option key={category._id} value={category.title}>
                        {category.title}
                    </option>))
            ,

            value: '',
            validation: {
                required: true
            },
            valid: false,
            touched: false
        },
    });

    const [formIsValid, setFormIsValid] = React.useState(false);

    const addProductData = event => {
        event.preventDefault();
        const formData = {};
        for (let formElementIdentifier in orderForm) {
            formData[formElementIdentifier] = orderForm[formElementIdentifier].value;
        }
        const product = {
            userId: userId,
            title: formData.title,
            price: formData.price,
            description: formData.description,
            category: formData.category
        }
        dispatch(productsActions.addProduct(product));
    }

    const inputChangedHandler = (event, inputIdentifier) => {
        const updatedFormElement = updateObject(orderForm[inputIdentifier], {
            value: event.target.value,
            valid: checkValidity(
                event.target.value,
                orderForm[inputIdentifier].validation
            ),
            touched: true
        });
        const updatedOrderForm = updateObject(orderForm, {
            [inputIdentifier]: updatedFormElement
        });

        let formIsValid = true;
        for (let inputIdentifier in updatedOrderForm) {
            formIsValid = updatedOrderForm[inputIdentifier].valid && formIsValid;
        }
        setOrderForm(updatedOrderForm);
        setFormIsValid(formIsValid);
    };

    const formElementsArray = [];
    for (let key in orderForm) {
        formElementsArray.push({
            id: key,
            config: orderForm[key]
        });
    }
    let form = (
        <form onSubmit={addProductData}>
            {formElementsArray.map(formElement => (
                <Input
                    key={formElement.id}
                    elementType={formElement.config.elementType}
                    elementConfig={formElement.config.elementConfig}
                    value={formElement.config.value}
                    label={formElement.config.label}
                    hint={formElement.config.hint}
                    invalid={!formElement.config.valid}
                    shouldValidate={formElement.config.validation}
                    touched={formElement.config.touched}
                    changed={event => inputChangedHandler(event, formElement.id)}
                />
            ))}
            <Button btnType="Success" disabled={!formIsValid}>ORDER</Button>

        </form>
    )

    return (
        <div class="wrapper">
            <Header />
            <article class="main">
                <div class="row">
                    <div class="item--1-4 image-block">
                        <div class="product-image-group">
                            <img class="product-image-big" src={`/${avatar}`} />
                            <hr class="border-divider" />
                            <input type="file" onChange={e => setAvatar(e.target.files[0].name)} name="imageUrl" id="imageUrl" />
                        </div>
                    </div>
                    <div class="item--3-4">
                        <div class="item-title">
                            <h3>Add product</h3>
                            <hr class="border-divider" />
                        </div>
                        {form}
                    </div>
                </div>
            </article>
            <LeftMenu />
        </div>
    )
}

Это строка в моем коде, связанная с этим полем выбора:

 elementConfig:
                categories.map(category => (
                    <option key={category._id} value={category.title}>
                        {category.title}
                    </option>))

person Oleg    schedule 02.01.2021    source источник


Ответы (1)


Это потому, что при первой загрузке этого компонента в categories нет ничего, а когда categories установлены, вы не устанавливаете данные orderForm снова. это называется stale props, вам нужно сделать следующее:


 useEffect(() => {
    setOrderForm((oldValue) => ({
      ...oldValue,
      category: {
        ...oldValue.category,
        elementConfig: categories.map((category) => (
          <option key={category._id} value={category.title}>
            {category.title}
          </option>
        )),
      },
    }));
 }, [categories])

Таким образом, каждый раз, когда categories данные изменяются, вы соответственно меняете состояние orderForm.

person Taghi Khavari    schedule 02.01.2021