ReactJS-在状态和道具之间传递数据
我有两个用于获取和呈现数据的组件。我想做的是在点击ReactJS-在状态和道具之间传递数据,reactjs,state,react-props,Reactjs,State,React Props,我有两个用于获取和呈现数据的组件。我想做的是在点击CarSearch组件时更改该按钮的标签(最好是CSS),搜索完成后,我想将基本的“搜索”标签放在那里 但是,当我单击“搜索”按钮并完成搜索时,标签“搜索”未设置,保留在那里的标签仍然是“过滤…”。现在有什么变化 也许我只是把它复杂化了,有更好的方法来实现它 class Car extends Component { constructor() { super(); this.state = {
CarSearch
组件时更改该按钮的标签(最好是CSS),搜索完成后,我想将基本的“搜索”标签放在那里
但是,当我单击“搜索”按钮并完成搜索时,标签“搜索”未设置,保留在那里的标签仍然是“过滤…”。现在有什么变化
也许我只是把它复杂化了,有更好的方法来实现它
class Car extends Component {
constructor() {
super();
this.state = {
cars: [],
searchBtn: 'Searchh'
}
}
componentDidMount() {
axios.get('/api/cars')
.then((response) => {
this.setState({cars: response.data});
console.log('cars: ', cars);
}).catch(err => {
console.log('CAUGHT IT! -> ', err);
});
}
handleSearch = () => {
axios.post('/api/cars/search', searchCars)
.then(response => {
this.setState({cars: response.data, searchBtn: 'Seach'}) // however, this `searchBtn` will not be passed to `CarSeach`
console.log('response.data: ', response.data);
})
}
render() {
return (
...
<CarAddNew />
<CarSearch
onSearch={this.handleSearch}
searchBtnLabel={this.state.searchBtn}
/>
<CarList cars={this.state.cars} />
)
}
}
export default class CarSearch extends Component {
constructor(props){
super(props);
searchBtn: props.searchBtnLabel
}
handleSearchSubmit(e) {
e.preventDefault();
this.setState({ searchBtn: 'Filtering...'});
this.props.onSearch(...)
}
render() {
return(
... search form ...
<button type="submit" className="btn btn-primary btn-sm mx-sm-2">
{this.state.searchBtn}
</button>
)
}
class汽车扩展组件{
构造函数(){
超级();
此.state={
汽车:[],
searchBtn:'Searchh'
}
}
componentDidMount(){
axios.get(“/api/cars”)
。然后((响应)=>{
this.setState({cars:response.data});
控制台日志('cars:',cars);
}).catch(错误=>{
log('catch IT!->',err);
});
}
handleSearch=()=>{
axios.post('/api/cars/search',searchCars)
。然后(响应=>{
this.setState({cars:response.data,searchBtn:'search'})//但是,此'searchBtn'不会传递给'CarSeach'`
日志('response.data:',response.data);
})
}
render(){
返回(
...
)
}
}
导出默认类CarSearch扩展组件{
建造师(道具){
超级(道具);
searchBtn:props.searchBtnLabel
}
无柄搜索提交(e){
e、 预防默认值();
this.setState({searchBtn:'Filtering…'});
这个.props.onSearch(…)
}
render(){
返回(
…搜索表单。。。
{this.state.searchBtn}
)
}
在这里,CarSearch
组件的构造函数
方法在安装后只会被调用一次。它将不再被调用。因此,当传入的searchBtnLabel
属性与您当前的状态不同时,您可以在CarSearch
组件中使用方法并设置状态
将以下代码放在CarSearch
构造函数调用之后
componentDidUpdate(){
if(this.props.searchBtnLabel!==this.state.searchBtn){
this.setState({searchBtn:this.props.searchBtnLabel});
}
}
这会解决你的问题
你在评论中提到过滤阶段没有发生。你可以像
handleSearchSubmit(e){
e、 预防默认值();
this.setState({searchBtn:'筛选…'),()=>{
this.props.onSearch(…);//setTimeout(()=>this.props.onSearch(…),N),其中N是毫秒。
});
}
说明:
setState
可以接受一个回调函数,一旦状态设置成功就会执行。即使在使用回调函数之后,如果您没有看到过滤文本,您也可以使用我提到的作为注释的setTimeout
。这里,CarSearch
组件的构造函数
方法将挂载后只能调用一次。它将永远不会被调用。因此,当传入的searchBtnLabel
属性与当前状态不同时,您可以在CarSearch
组件中使用方法并设置状态
将以下代码放在CarSearch
构造函数调用之后
componentDidUpdate(){
if(this.props.searchBtnLabel!==this.state.searchBtn){
this.setState({searchBtn:this.props.searchBtnLabel});
}
}
这会解决你的问题
你在评论中提到过滤阶段没有发生。你可以像
handleSearchSubmit(e){
e、 预防默认值();
this.setState({searchBtn:'筛选…'),()=>{
this.props.onSearch(…);//setTimeout(()=>this.props.onSearch(…),N),其中N是毫秒。
});
}
说明:
setState
可以接受一个回调函数,该函数将在状态设置成功后执行。即使在使用回调函数之后,如果您没有看到过滤文本,您也可以使用我提到的作为注释的setTimeout
。正如您所写的,有两个组件(Car
和CarSearch
)试图控制标签。使用React的最佳方法是拥有“黄金”真相来源
有两种方法可以实现这一目标:
父级是搜索组件状态的黄金来源。
让您的CarSearch
呈现从Car
传递给它的标签。您甚至可以将CarSearch组件设置为无状态
export default class CarSearch extends Component {
handleSearchSubmit(e) {
e.preventDefault();
this.props.onSearch(...)
}
render() {
return(
... search form ...
<button type="submit" className="btn btn-primary btn-sm mx-sm-2">
{this.props.searchBtnLabel}
</button>
)
}
}
CarSearch
组件处理与搜索相关的一切。
需要考虑的其他提示:
选择哪一个
这取决于组件的责任是什么。对于搜索时的e.x,如果您想在Car
中的其他组件上反映这一点,对于搜索时禁用AddCar的e.x,则应由父级负责。如果不是,搜索组件可以拥有搜索状态
另一个提示,与其依赖标签来显示,我建议您维护搜索组件的状态。对于e.x,您的搜索可能有许多状态:
初始|搜索|搜索失败|搜索成功,记录数为0 |搜索成功,记录数超过0
使搜索状态显式,可以以更可预测的模式控制渲染
class CarSearch extends Component {
state: {
searchState: 'Initial',
searchTerm: ''
}
onSearch () => {
this.setState({searchState: 'Searching'})
axios.post(---)
.then(this.setState({searchState: 'Success'}))
.catch(this.setState({searchState: 'Error'}))
}
render() {
// change styles, conditional rendering, show toast etc. based on the state
}
}正如您所写,有两个组件(
Car
和CarSearch
)试图控制标签。使用React的最佳方法是拥有“黄金”真相来源
有两种方法可以实现这一目标:
父级是搜索组件状态的黄金来源。
让你的C
export default class CarSearch extends Component {
handleSearchSubmit(e) {
e.preventDefault();
this.setState({searchBtn: 'Filtering...'});
axios.post('/api/cars/search', searchCars)
.then(response => {
this.setState({searchBtn: 'Search'});
this.props.onSearch(response.data);
})
}
}
render() {
return(
... search form ...
<button type="submit" className="btn btn-primary btn-sm mx-sm-2">
{this.state.searchBtn}
</button>
)
}
}
handleSearch = (data) => {
this.setState({cars: data})
}
class CarSearch extends Component {
state: {
searchState: 'Initial',
searchTerm: ''
}
onSearch () => {
this.setState({searchState: 'Searching'})
axios.post(---)
.then(this.setState({searchState: 'Success'}))
.catch(this.setState({searchState: 'Error'}))
}
render() {
// change styles, conditional rendering, show toast etc. based on the state
}