React 下拉列表组件选择的值最初未绑定
React Dropdown List Component Selected Value not Bound Initially
我的 react/redux/es6 应用程序中有一个无状态下拉列表组件。我将其选择的值存储在状态中,以便记住先前选择的值。然而,每次用户导航到此页面时,下拉列表的值最初都没有正确选择。触发视图重新呈现的任何操作都会正确设置值。
我可以确认每次都正确地将值传递给下拉列表组件,包括第一次呈现视图时。
const DropDownList = ({name, label, options, selectedValue, error, onChange}) => {
let wrapperClass = 'form-group';
if (error && error.length > 0) {
wrapperClass += " " + 'has-error';
}
let optionsMarkup = [];
for(let i=0;i<options.length;i++){
optionsMarkup.push(<option key={options[i]}>{options[i]}</option>);
}
return (
<div className={wrapperClass}>
<label htmlFor={name} className="control-label">{label}</label>
<select name={name} title="Please select" data-live-search="true" className="form-control" onChange={onChange} value={selectedValue}>
{optionsMarkup}
</select>
</div>
);
};
看起来很简单。有一个无状态组件将值传递给这个组件:
const SearchForm = ({name, onSubmit, topText, onSearchTermChange, onCategoryChange, submitting, errors, searchResults, searchTerm, searchCategory}) => {
const reasons = ['Select a Reason for Search',
'A',
'B',
'C',
'D'];
return (
<section>
<ErrorSummary errors={errors} />
<p>{topText}</p>
<form role="form">
<TextInput
name="searchTerms"
label="Search Terms"
placeholder="Example search here"
type="text"
error={errors.title}
onChange={onSearchTermChange}
value={searchTerm} />
<DropDownList
name={name}
label="Seaarch Reason"
options ={reasons}
selectedValue={searchCategory}
onChange={onCategoryChange} />
<div className="col-md-2 col-xs-12">
<button type="submit" className="btn btn-primary col-md-12" onClick={onSubmit} disabled={submitting}>{submitting ? "Searching" : "Search"}</button>
</div>
</form>
</section>
);
};
还有一个包含两个 SearchForm 的有状态组件,传递事件处理程序:
render() {
return(
<section>
<div className="tab-content">
<div className="col-md-12 tab-pane active" role="tabpanel" id="searchPage">
<div className="container">
<div className="row">
<div className="col-md-12 well center-block">
<nav role="navigation">
<ul className="nav nav-pills nav-justified">
<li role="presentation" className={this.props.searchView == "searchOne" ? "active" : ""}><a href="#searchOne" data-toggle="tab" onClick={this.searchViewChanged.bind(null, "searchOne")}>search One</a></li>
<li role="presentation" className={this.props.searchView == "searchTwo" ? "active" : ""}><a href="#searchTwo" data-toggle="tab" onClick={this.searchViewChanged.bind(null, "searchTwo")}>search Two</a></li>
</ul>
</nav>
<div className="tab-content">
<div className={this.props.searchView == "searchOne" ? "col-md-12 well tab-pane active" : "col-md-12 well tab-pane"} role="tabpanel" id="searchOne">
<SearchForm
name="searchOne"
onSubmit={this.searchOne}
topText="search one text"
submitting={this.state.submitting}
errors={this.state.searchOneErrors}
onSearchTermChange={this.searchOneTermChanged}
onCategoryChange={this.searchOneCategoryChanged}
searchResults={this.props.searchOneSearchResults}
searchTerm={this.state.searchOneTerm}
searchCategory={this.state.searchOneCategory} />
</div>
<div className={this.props.searchView == "searchTwo" ? "col-md-12 well tab-pane active" : "col-md-12 well tab-pane"} role="tabpanel" id="searchTwo">
<SearchForm
name="searchTwo"
onSubmit={this.searchTwo}
topText="search Two text"
submitting={this.state.submitting}
errors={this.state.searchTwoSearchErrors}
onSearchTermChange={this.searchTwoSearchTermChanged}
onCategoryChange={this.searchTwoCategoryChanged}
searchTerm={this.state.searchTwoTerm}
searchCategory={this.state.searchTwoCategory} />
</div>
</div>
</div>
</div>
....
....
</div>
</div>
</div>
</section>
我不知道为什么会这样。有什么想法吗?
也许这与你传递道具的方式有关?
searchTerm={this.state.searchTwoTerm}
为什么直接使用this.state。由于您使用的是 redux,因此更好的方法是调用 mapStateToProps 并连接组件(然后使用 this.props)
文档:http://redux.js.org/docs/basics/UsageWithReact.html
不过这只是一个想法,不知道是不是问题。
第二个想法是,您可能没有在 reducer 中设置 searchTwoTerm 的默认值,因此如果您刷新页面,持久化状态消失,默认值进入。(但您写道,即使是第一次渲染组件,价值也很好..所以它也可能不是这种情况)。
我不相信这是多么简单。我只需将 "value" 添加到选项,一切就绪。不确定为什么它在没有值属性的情况下重新渲染。因此,DropdownList 组件中的 for 循环应如下所示:
for(let i=0;i<options.length;i++){
optionsMarkup.push(<option key={options[i]} value={options[i]}>{options[i]}</option>);
}
我的 react/redux/es6 应用程序中有一个无状态下拉列表组件。我将其选择的值存储在状态中,以便记住先前选择的值。然而,每次用户导航到此页面时,下拉列表的值最初都没有正确选择。触发视图重新呈现的任何操作都会正确设置值。
我可以确认每次都正确地将值传递给下拉列表组件,包括第一次呈现视图时。
const DropDownList = ({name, label, options, selectedValue, error, onChange}) => {
let wrapperClass = 'form-group';
if (error && error.length > 0) {
wrapperClass += " " + 'has-error';
}
let optionsMarkup = [];
for(let i=0;i<options.length;i++){
optionsMarkup.push(<option key={options[i]}>{options[i]}</option>);
}
return (
<div className={wrapperClass}>
<label htmlFor={name} className="control-label">{label}</label>
<select name={name} title="Please select" data-live-search="true" className="form-control" onChange={onChange} value={selectedValue}>
{optionsMarkup}
</select>
</div>
);
};
看起来很简单。有一个无状态组件将值传递给这个组件:
const SearchForm = ({name, onSubmit, topText, onSearchTermChange, onCategoryChange, submitting, errors, searchResults, searchTerm, searchCategory}) => {
const reasons = ['Select a Reason for Search',
'A',
'B',
'C',
'D'];
return (
<section>
<ErrorSummary errors={errors} />
<p>{topText}</p>
<form role="form">
<TextInput
name="searchTerms"
label="Search Terms"
placeholder="Example search here"
type="text"
error={errors.title}
onChange={onSearchTermChange}
value={searchTerm} />
<DropDownList
name={name}
label="Seaarch Reason"
options ={reasons}
selectedValue={searchCategory}
onChange={onCategoryChange} />
<div className="col-md-2 col-xs-12">
<button type="submit" className="btn btn-primary col-md-12" onClick={onSubmit} disabled={submitting}>{submitting ? "Searching" : "Search"}</button>
</div>
</form>
</section>
);
};
还有一个包含两个 SearchForm 的有状态组件,传递事件处理程序:
render() {
return(
<section>
<div className="tab-content">
<div className="col-md-12 tab-pane active" role="tabpanel" id="searchPage">
<div className="container">
<div className="row">
<div className="col-md-12 well center-block">
<nav role="navigation">
<ul className="nav nav-pills nav-justified">
<li role="presentation" className={this.props.searchView == "searchOne" ? "active" : ""}><a href="#searchOne" data-toggle="tab" onClick={this.searchViewChanged.bind(null, "searchOne")}>search One</a></li>
<li role="presentation" className={this.props.searchView == "searchTwo" ? "active" : ""}><a href="#searchTwo" data-toggle="tab" onClick={this.searchViewChanged.bind(null, "searchTwo")}>search Two</a></li>
</ul>
</nav>
<div className="tab-content">
<div className={this.props.searchView == "searchOne" ? "col-md-12 well tab-pane active" : "col-md-12 well tab-pane"} role="tabpanel" id="searchOne">
<SearchForm
name="searchOne"
onSubmit={this.searchOne}
topText="search one text"
submitting={this.state.submitting}
errors={this.state.searchOneErrors}
onSearchTermChange={this.searchOneTermChanged}
onCategoryChange={this.searchOneCategoryChanged}
searchResults={this.props.searchOneSearchResults}
searchTerm={this.state.searchOneTerm}
searchCategory={this.state.searchOneCategory} />
</div>
<div className={this.props.searchView == "searchTwo" ? "col-md-12 well tab-pane active" : "col-md-12 well tab-pane"} role="tabpanel" id="searchTwo">
<SearchForm
name="searchTwo"
onSubmit={this.searchTwo}
topText="search Two text"
submitting={this.state.submitting}
errors={this.state.searchTwoSearchErrors}
onSearchTermChange={this.searchTwoSearchTermChanged}
onCategoryChange={this.searchTwoCategoryChanged}
searchTerm={this.state.searchTwoTerm}
searchCategory={this.state.searchTwoCategory} />
</div>
</div>
</div>
</div>
....
....
</div>
</div>
</div>
</section>
我不知道为什么会这样。有什么想法吗?
也许这与你传递道具的方式有关?
searchTerm={this.state.searchTwoTerm}
为什么直接使用this.state。由于您使用的是 redux,因此更好的方法是调用 mapStateToProps 并连接组件(然后使用 this.props) 文档:http://redux.js.org/docs/basics/UsageWithReact.html
不过这只是一个想法,不知道是不是问题。
第二个想法是,您可能没有在 reducer 中设置 searchTwoTerm 的默认值,因此如果您刷新页面,持久化状态消失,默认值进入。(但您写道,即使是第一次渲染组件,价值也很好..所以它也可能不是这种情况)。
我不相信这是多么简单。我只需将 "value" 添加到选项,一切就绪。不确定为什么它在没有值属性的情况下重新渲染。因此,DropdownList 组件中的 for 循环应如下所示:
for(let i=0;i<options.length;i++){
optionsMarkup.push(<option key={options[i]} value={options[i]}>{options[i]}</option>);
}