React app, можно ли создать такой компонент?

Всем привет, столкнулся с дурацким хотением, а именно:
Можно ли в react-е сделать, что бы компонента возвращала измененную переменную ?
Есть родительская компонента

class Parent extends React.Component {

    constructor(props) {
        super(props);

        this.state = {
            value1: "",
            value2: "",
            value3: "",
        };

        this.handleOnClick = this.handleOnClick.bind(this);

        this.elements = [
            {
                className: "parent__input parent__input--1",
                type: "text",
                val: this.state.value1,
                placeholder: "placeholder1"
            },
            {
                className: "parent__input parent__input--1",
                type: "text",
                val: this.state.value2,
                placeholder: "placeholder2"
            },
            {
                className: "parent__input parent__input--1",
                type: "text",
                val: this.state.value3,
                placeholder: "placeholder3"
            },
        ]
    }

    handleOnClick() {
        console.log(this.state.value1, this.state.value2, this.state.value3);
    }

    render() {
        return (
            <>
                {this.elements.map((element, index) => {
                    return (<Child key={index} className={element.className} type={element.type} value={element.val}
                                   placeholder={element.placeholder}/>)
                })}

                <div style={{marginTop: "10px"}}>
                    <span onClick={this.handleOnClick}>Кнопка</span>
                </div>
            </>
        )
    }
}


Есть дочерня компонента

const Child = ({className, type, value, placeholder}) => {

    const [innerValue, setInnerValue] = useState(value);

    const handleOnChange = (e) => {
        setInnerValue(e.target.value)
    };

    return (
        <div className={"input"}>
            <input onChange={handleOnChange} className={"input__field" + (className ? ` ${className}` : '')} type={type ? type : 'text'}
                   value={innerValue}/>
            {placeholder && <span className={"input__placeholder"}>{placeholder}</span>}
        </div>
    )
};



this.state - эмитирует данные из редьюсера

this.state = {
            value1: "1",
            value2: "2",
            value3: "3",
        };



Проблема вот в чем, сейчас после заполнения полей и нажатии на кнопку в родительской компоненте, я как полагается не получу новые значения переменных (value1, value2, value3), можно ли как-то сделать, что бы дочерний компонент изменял ту переменную, которую я передаю в него через параметры ?

Сейчас пользуюсь, как мне кажется граблями:
Передаю функцию из родителя, которая принимает параметром новую строку и вызываю ее во время события onChange (при таком подходе, я не знаю какая именно это переменная изменяется), можно дочернему компоненту предавать индификатор этой переменной в роле id и его же передавать в родительскую функцию вторым параметром, но тогда нужно как то делать перебор каждой переменной, а это не удобно...



Я хочу добиться такого результата:
У меня есть массив переменных из редьюсера, которые отвечают за поля ввода, я с помощью map создаю компоненты, передаю им эти переменные из редьюсера, при заполнении эти переменные изменяются, после чего нажатием на кнопку отправляю эти переменные обратно в редюсер

Заранее спасибо.
  • Вопрос задан
  • 105 просмотров
Решения вопроса 1
rockon404
@rockon404 Куратор тега React
Frontend Developer
1 Не храните состояние форм в редьюсере. В большинстве случаев в этом нет необходимости.

2. Уберите внутреннее состояние значения value из Input. Сейчас у вас получается два источника правды, но для чего они вам, я полагаю, вы и сами не понимаете.

3. Старайтесь не нарушать нативных интерфейсов без необходимости.
Ваш код:
handleParentOnChange(id, newValue) {}
handleParentOnChange(e.target.id, e.target.value);

Как следовало сделать:
handleParentOnChange(e) {}
handleParentOnChange(e);

4. Оптимизируйте повторяющийся код в handleParentOnChange. И вместо id используйте атрибут name.
handleParentOnChange(e) {
  const { name, value } = e.target;
  this.setState({
    [name]: value,
  });
}
Ответ написан
Пригласить эксперта
Ответы на вопрос 2
Robur
@Robur
Знаю больше чем это необходимо
То что вы делаете - это правильно. передавайте переменную и onChange, в нем меняйте эту переменную, храните все в стейте родителя. Если проблемы с тем чтобы в onChange поменять нужную переменную - это решаемо - это и решайте.
Так как вы хотите сделать тоже можно, но это будет даже не грабли а весьма плохой код, чтобы не плодить количество говнокода на планете, не буду объяснять как.
Ответ написан
Ваш ответ на вопрос

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

Войти через центр авторизации
Похожие вопросы
29 мар. 2024, в 10:00
10000 руб./за проект
29 мар. 2024, в 09:59
750 руб./в час
29 мар. 2024, в 09:55
50000 руб./за проект