Как передать значение из пользовательского класса компонента в Redux-форму?
Я вызываю пользовательский компонент в моей редукционной форме.
<Field name="myField" component={SiteProjectSelect}/>
Этот компонент представляет собой комбинацию из двух полей со списком. Второе поле зависит от значения первого на - то есть, в зависимости от того, какой сайт вы выбираете, вы можете выбрать из списка проектов. Что я хотел бы сделать, это получить форму для получения выбранного сайта и выбранных проектов. Тем не менее, я не уверен, как передать значения в избыточную форму.
class SiteProjectSelect extends Component {
constructor() {
super();
this.state = {
selectedSite: null,
selectedProject: null,
};
}
handleSiteSelection = selectedSite => {
console.log(selectedSite)
this.setState({ selectedSite, selectedProject: null });
};
handleProjectSelection = selectedProject => {
this.setState({ selectedProject });
this.props.input.onChange(selectedProject.value);
};
render() {
const selectedRow = this.state.selectedSite ? projects.find((node) => node.site === this.state.selectedSite.value) : "";
const filteredProjectOptions = selectedRow ? selectedRow.projects.map(project => ({ value: project, label: project })) : []
return (
<div {...this.props} >
<label>Site</label>
<div style={{ marginBottom: '20px' }} >
<Select
name="site"
value={this.state.selectedSite}
onChange={this.handleSiteSelection}
options={siteOptions}
isSearchable
/>
</div>
<div style={{ marginBottom: '20px' }} >
<label>Project</label>
<Select
name="project"
value={this.state.selectedProject}
onChange={this.handleProjectSelection}
options={filteredProjectOptions}
isMulti
isSearchable
closeMenuOnSelect={false}
/>
</div>
</div>
);
}
}
1 ответ
Я наконец понял это. Для всех, кто сталкивается с этим, вот что мне нужно было знать. Чтобы использовать пользовательский компонент,
- Использовать
onChange
опору для установки нового значения поля. Вы делаете это, вызываяonChange
функция,this.props.input.onChange(your-components-new-value-here)
когда вам нужно изменить значение компонента и передать ему новое значение. - Это новое значение теперь будет сохранено в
value
проп:this.props.input.value
, Поэтому, где бы в функции рендеринга для вашего компонента вам не приходилось передавать / отображать текущее значение вашего компонента, используйтеvalue
двигательный Это должно бытьvalue
prop, а не другая переменная, такая как то, что вы передали своей функции onChange. То, что это делает, дает контроль над тем, что отображается в состоянии вашей редукс-формы, котораяvalue
опора связана с. Почему это полезно? Например, вы можете перевести пользователя на страницу просмотра формы после завершения, а затем вернуться к форме, если пользователь хочет внести дополнительные изменения. Как в приукрашенной форме узнать, как заново заполнить все, что отображается, не заставляя пользователя снова заполнять форму? Потому что отображение зависит от состояния, а не от ввода пользователя! Мне понадобилось время, чтобы разобраться во всем этом!!
В моем примере, где я использовал два react-select
Компоненты, один из которых зависел от другого, в итоге мне пришлось использовать компонент Fields, что позволило мне иметь два поля в моем компоненте, а не только одно. После того, как я это реализовал, стало также очевидно, что мне не нужно иметь отдельное состояние внутри моего компонента, так как значение обоих полей всегда доступно через value
опора для каждого из них. Так что да, я мог бы использовать функцию без сохранения состояния!
Я называю свой компонент с помощью:
<Fields names={["site", "projects"]} component={SiteProjectSelect} />
Мой последний рабочий компонент:
class SiteProjectSelect extends Component {
handleSiteSelection = selectedSite => {
this.props.site.input.onChange(selectedSite);
this.props.projects.input.onChange(null);
};
handleProjectSelection = selectedProjects => {
this.props.projects.input.onChange(selectedProjects);
};
renderSite = () => {
const {
input: { value },
meta: { error, touched }
} = this.props.site;
return (
<div>
<label>Site</label>
<div style={{ marginBottom: '20px' }}>
<Select
name="site"
value={value}
onChange={this.handleSiteSelection}
options={siteOptions}
isSearchable
/>
</div>
<div className="red-text" style={{ marginBottom: '20px' }}>
{touched && error}
</div>
</div>
);
};
renderProjects = () => {
var {
input: { value },
meta: { error, touched }
} = this.props.projects;
const selectedSite = this.props.site.input.value;
const selectedRow = selectedSite
? projects.find(node => node.site === selectedSite.value)
: '';
const filteredProjectOptions = selectedRow
? selectedRow.projects.map(project => ({
value: project,
label: project
}))
: [];
return (
<div>
<div style={{ marginBottom: '20px' }}>
<label>Projects</label>
<Select
name="projects"
value={value}
onChange={this.handleProjectSelection}
options={filteredProjectOptions}
isMulti
isSearchable
closeMenuOnSelect={false}
/>
</div>
<div className="red-text" style={{ marginBottom: '20px' }}>
{touched && error}
</div>
</div>
);
};
render() {
return (
<div>
{this.renderSite()}
{this.renderProjects()}
</div>
);
}
}