我正在构建我的第一个React应用程序。我正在尝试从react-router-dom渲染一些路由。 从主要组件我调用我的api获取一个json对象,然后我更新状态。问题是我的子组件在设置新状态后没有重新渲染,因此我在子组件中没有道具。我使用了一些函数,如forcerender和componentWillReceiveProps,但仍然无法正常工作
我确定这不是一个大问题,但我一直试图解决这个问题几个小时,但我无法让它发挥作用。
这是我最近的尝试:
class DetectorEfficiencyCalculator extends Component {
constructor(props) {
super(props);
this.state = {
detectors: []
};
axios.get(`/detectors`)
.then(res => {
const detectors = res.data;
this.setState({ detectors });
console.log('state updated')
});
}
render() {
return (
<div className="DetectorEfficiencyCalculator">
<RoutesHandler detectors={this.state.detectors}/>
</div>
);
}
}
class RoutesHandler extends Component{
constructor(props) {
super(props);
this.state = { detectors: props.detectors } ;
}
componentWillReceiveProps(nextProps) {
this.setState({detectors:nextProps.detectors})
this.forceUpdate()
}
render() {
console.log('render')
return (
<div className="RoutesHandler">
<Switch>
<Route exact path='/frontend/Detectors' component={DetectorList} detectors={this.props.detectors}/>
<Route path='/frontend/Detectors/:number' component={DetectorDetail} detectors={this.props.detectors}/>
</Switch>
</div>
);
}
}
class DetectorList extends Component {
render () {
console.log('renderList')
if (!this.props.detectors) {
return null;
}
return (
<ul>
{this.props.detectors.map(u => {
return (
<Detector
id={u.id}
name={u.name}
single={u.single}
threshold={u.threshold}
angle={u.angle}
/>
);
})}
</ul>
);
}
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
提前感谢您的帮助:)
答案 0 :(得分:0)
尝试这样的事情:
class DetectorEfficiencyCalculator extends Component {
state={detectors:[]}
componentDidMount(){
const self = this;
axios.get(`/detectors`) //do it here...
.then(res => {
const detectors = res.data;
self.setState({ detectors });
console.log('state updated')
});
}
render() {
return (
<div className="DetectorEfficiencyCalculator">
<RoutesHandler detectors={this.state.detectors}/>
</div>
);
}
}
class RoutesHandler extends Component{
render() {
console.log('render')
return (
<div className="RoutesHandler">
<Switch>
<Route exact path='/frontend/Detectors' component={DetectorList} detectors={this.props.detectors}/>
<Route path='/frontend/Detectors/:number' component={DetectorDetail} detectors={this.props.detectors}/>
</Switch>
</div>
);
}
}
class DetectorList extends Component {
render () {
console.log('renderList')
if (!this.props.detectors) {
return null;
}
return (
<ul>
{this.props.detectors.map(u => {
return (
<Detector
id={u.id}
name={u.name}
single={u.single}
threshold={u.threshold}
angle={u.angle}
/>
);
})}
</ul>
);
}
}
&#13;
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
&#13;
基本上,您不希望在构造函数中执行任何ajax调用或db访问,这不是在React中执行此操作的正确方法,因为可以多次调用构造函数。而是使用React组件生命周期方法componentDidMount来启动api调用。另外我使用变量(self)来保存对组件的引用(this),这样我就可以在axios promise处理程序中使用它。
答案 1 :(得分:0)
好的,我进入了解决方案:路由渲染了一个函数,我在其中渲染组件并使用我需要的道具加载它。
this.RenderDetectorDetail = (props) => {
return (
<DetectorDetail detectors={this.props.detectors}/>
);
};
<Route exact path='/frontend/Detectors' render={this.RenderDetectorList} />