我是React.js的新手,但我喜欢研究新的东西并坚持这项任务。我有两个分层组件,当我更新父级状态时,子组件不会重新呈现。
我在父级中有onChange事件的元素。当发生更改时,我正在从REST请求JSON并在父级设置状态。然后在这个方法中,我正在调用具有由更改状态组成的数据属性的子组件的渲染。没有任何反应。它只发生在ONCE。选择下一个选项并不会做任何事情。
有经验的人可以快速查看我的代码并向我解释如何实现它。
import React, { Component } from 'react';
import ReactDOM from "react-dom";
import $ from "jquery";
import './App.css';
import "../node_modules/bootstrap/dist/css/bootstrap.min.css";
import cafeList from "./cafeList.json";
class App extends Component {
render() {
return (
<div className="App container">
<div className="App-header">
<h2>Dining Rooms Menu </h2>
</div>
<CafeSelect />
</div>
);
}
}
class CafeSelect extends Component{
constructor(props) {
super(props);
this.state = {
cafeList: cafeList,
goods_for_current_cafe: []
};
this.handleChange = this.handleChange.bind(this);
}
handleChange(){
var self = this;
var cur_val_cafe = $('#select-cafe-type').find(":selected").val();
console.log(cur_val_cafe);
$.ajax({
url: 'https://example.com/rest',
type: 'POST',
data: {
auth: 'authkey',
getcafeguide: 1,
idpoint: cur_val_cafe,
},
})
.done(function(res) {
var data = $.parseJSON(res);
self.setState({
goods_for_current_cafe: data
});
console.log(self.state);
ReactDOM.render(
<GoodsGroup
data={self.state.goods_for_current_cafe}
/>,
document.getElementById("goods-group")
);
})
}
render() {
return(
<div>
<div className="row">
<label className="col-lg-2">Choose dining room</label>
<div className="control-wrapper col-lg-10">
<select className="form-control" id="select-cafe-type" onChange={this.handleChange}>
{cafeList.map(function(cafe, index){
return <option key={ index } value={cafe.IDPoint}>{cafe.Point}</option>;
})}
</select>
</div>
</div>
<div id="goods-group"></div>
<div id="goods-list"></div>
</div>
)
}
}
class GoodsGroup extends Component{
constructor(props) {
super(props);
this.handleChange = this.handleChange.bind(this);
}
handleChange(){
var cur_group_val = $('#select-goods-type').find(":selected").val();
var matches = $.grep(this.props.data, function(e) { return e.GoodsGroup == cur_group_val });
ReactDOM.render(
<GoodsList
data={matches}
/>,
document.getElementById("goods-list")
);
}
componentWillMount() {
console.log(this.props.data);
let _ = require('underscore');
var data = this.props.data;
let categories = _.keys(_.countBy(data, function(data) {
return data.GoodsGroup;
}));
this.setState({
categories: categories,
goods: this.props.data
});
}
render() {
return (
<div className="row">
<label className="col-lg-2">Choose goods category</label>
<div className="control-wrapper col-lg-10">
<select className="form-control" id="select-goods-type" onChange={this.handleChange}>
{this.state.categories.map(function(group, index){
return <option key={ index } value={group}>{group}</option>;
})}
</select>
</div>
</div>
)
}
}
export default App;
答案 0 :(得分:1)
这是 mvp 更改以使其正常工作。
在您的GoodsGroup组件中,将componentWillMount函数更改为以下
prepareData() {
console.log(this.props.data);
let _ = require('underscore');
var data = this.props.data;
return _.keys(_.countBy(data, function(data) {
return data.GoodsGroup;
}));
}
并且您的渲染功能必须更改为
render() {
const categories = this.prepareData();
return (
<div className="row">
<label className="col-lg-2">Choose goods category</label>
<div className="control-wrapper col-lg-10">
<select className="form-control" id="select-goods-type" onChange={this.handleChange}>
{categories.map(function (group, index) {
return <option key={index} value={group}>{group}</option>;
})}
</select>
</div>
</div>
)
}
如果React元素先前已渲染到容器中,则会对其执行更新,并仅根据需要改变DOM以反映最新的React元素。
由于在重新渲染时GoodsGroup组件已存在,因此不会调用componentWillMount函数。所以我们改变它以便总是在渲染时调用。
答案 1 :(得分:1)
componentWillMount - 生命周期方法仅适用于 ONCE ,即安装发生时,componentWillMount内的状态更改不会触发重新呈现请参阅https://facebook.github.io/react/docs/react-component.html#componentwillmount 对于您的方案,在首次选择期间已经发生了安装。
尝试使用以下,
选项1:使用shouldComponentUpdate并在render()
下移动类别获取方法getCategories() {
const data = this.props.data;
return _.keys(_.countBy(data, (data) => data.GoodsGroup))
}
shouldComponentUpdate(nextProps) {
return !R.equals(this.props, nextProps)// using ramda for comparison
}
render() {
const categories = this.getCategories()
return (
<div className="row">
<label className="col-lg-2">Choose goods category</label>
<div className="control-wrapper col-lg-10">
<select className="form-control" id="select-goods-type" onChange={this.handleChange}>
{categories.map(function (group, index) {
return <option key={index} value={group}>{group}</option>;
})}
</select>
</div>
</div>
)
选项2:否则使用componentWillReceiveProps()
getCategories(props) {
const data = props.data;
return _.keys(_.countBy(data, (data) => data.GoodsGroup))
}
componentWillMount() {
const categories = this.getCategories(this.props)
this.setState({
categories: categories,
goods: this.props.data
})
}
componentWillReceiveProps(nextProps) {
const categories = this.getCategories(nextProps)
this.setState({
categories: categories,
goods: nextProps.data
})
}
render() {
return (
<div className="row">
<label className="col-lg-2">Choose goods category</label>
<div className="control-wrapper col-lg-10">
<select className="form-control" id="select-goods-type" onChange={this.handleChange}>
{this.state.categories.map(function (group, index) {
return <option key={index} value={group}>{group}</option>;
})}
</select>
</div>
</div>
)