javascript - onChange 和 setState 在我的代码中不能一起工作
问题描述
我正在尝试构建一个搜索框。但是,当我想在输入内容时设置状态时,该框根本不允许我输入任何内容。
这是调用搜索框组件的类
export default class Tagsearch extends Component {
constructor(props) {
super(props);
this.state = {
hitsDisplay:false,
inputContent:"",
tags:[]
};
}
openDisplay = () => {
console.log("open")
// this.setState({ hitsDisplay: true })
}
closeDisplay = () => {
console.log("close")
// this.setState({ hitsDisplay: false })
}
render() {
let inputTags = (
this.state.tags.map((tag, i) =>
<li key={i} style={styles.items}>
{tag}
<button onClick={() => this.handleRemoveItem(i)}>
(x)
</button>
</li>
)
)
let result = (
<div className="container-fluid" id="results">
</div>
)
if (this.state.hitsDisplay) {
result = (
<div className="container-fluid" id="results">
<div className="rows">
<MyHits handleSelect={this.handleSelect}/>
</div>
<div className="rows">
<Pagination />
</div>
</div>
)
}
return (
<InstantSearch
appId="*******"
apiKey="***********************"
indexName="tags"
>
{inputTags}
<SearchBox
connectSearchBox={connectSearchBox}
openDisplay={this.openDisplay}
closeDisplay={this.closeDisplay}
/>
{result}
</InstantSearch>
)
}
}
以下是搜索框组件
const SearchBox = props => {
let {
connectSearchBox,
openDisplay,
closeDisplay
} = props;
const CustomSearchBox = connectSearchBox(({ currentRefinement, refine }) => {
const handleChange = (e, refine) => {
refine(e.target.value)
// console.log(e.target.value)
if (e.target.value !== "") {
openDisplay();
} else {
closeDisplay();
}
}
return (
<label>
<ul style={styles.container}>
<input
style={styles.input}
type="text"
value={currentRefinement}
onChange={e => handleChange(e, refine)}
/>
</ul>
</label>
)
})
return (
<CustomSearchBox />
)
}
export default SearchBox;
如果我在 open & closeDisplay 中评论这两个 setState,它工作正常,它会相应地打印出打开和关闭。但是,一旦启用 setState,输入框根本不允许我输入任何内容。
任何帮助表示赞赏。
解决方案
你的代码写错了。connectSearchBox
旨在将组件连接到 Algolia api。这是对组件定义的一次性设置。它返回一个用 api 特性包装给定组件的高阶组件。您可以在此处查看源代码。通过将您的自定义 SearchBox 放在 SearchBox 函数中,您将导致组件在每个 render() 循环中重新构建和重新连接,从而不保留状态。这就是为什么一旦您setState
的搜索文本消失。
import { connectSearchBox } from 'react-instantsearch-dom';
const CustomSearchBox = ({ currentRefinement, refine, openDisplay, closeDisplay, ...props }) => {
const handleChange = (e, refine) => {
refine(e.target.value)
if (e.target.value !== "")
openDisplay();
else
closeDisplay();
}
return (
<label>
<ul style={styles.container}>
<input
style={styles.input}
type="text"
value={currentRefinement}
onChange={e => handleChange(e, refine)}
/>
</ul>
</label>
)
})
export default connectSearchBox(CustomSearchBox);
用法
import CustomSearchBox from './CustomSearchBox'
...
<CustomSearchBox
openDisplay={this.openDisplay}
closeDisplay={this.closeDisplay}
/>
文档中的使用示例。我认为您试图实现的是将道具传递给您的组件,但connectSearchBox
已经保证您传递给 HOC 的任何道具也将传递给您的自定义搜索框。335号线
推荐阅读
- javascript - 将字符串与 getDate 匹配,如果匹配则执行点击操作
- reactjs - 找不到预设“@babel/preset-env”
- javascript - 由于使用双引号解析的问题,将序列化的 JSON 字符串用单引号括起来
- java - 通过 .jar 部署 Jetty 服务器。为什么我无法访问索引?
- unit-testing - 将 Generic.List 转换为 System.Threading.Task.Generic.List 时出现问题
- python - 简单的 Travis-CI BUILD 给出“没有设置环境变量”
- java - 使用 Java 在 intelliJ 的新窗口中进行多项目
- docker - 在应用程序远程安装时创建 Docker 映像
- gradle - Crashlytics gradle crashlyticsUploadSymbolsRelease 和 Android 应用程序包
- java - 使用 Java 绑定识别 OpenCV 丢失的 DLL