异步调用后渲染路由
Render Route after asynchronous call
我正在构建我的第一个 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>
提前感谢您的帮助:)
尝试这样的事情:
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>
);
}
}
<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>
基本上,您不想在构造函数中执行任何 ajax 调用或数据库访问,这不是在 React 中执行此操作的正确方法,因为可以多次调用构造函数。而是使用 React 组件生命周期方法 componentDidMount 来启动 api 调用。此外,我还使用了一个变量 (self) 来保存对组件 (this) 的引用,因此我可以在 axios promise 处理程序中使用它。
好的,我进入了解决方案:路由呈现一个函数,我在其中呈现组件并使用我需要的道具加载它。
this.RenderDetectorDetail = (props) => {
return (
<DetectorDetail detectors={this.props.detectors}/>
);
};
<Route exact path='/frontend/Detectors' render={this.RenderDetectorList} />
我正在构建我的第一个 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>
提前感谢您的帮助:)
尝试这样的事情:
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>
);
}
}
<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>
基本上,您不想在构造函数中执行任何 ajax 调用或数据库访问,这不是在 React 中执行此操作的正确方法,因为可以多次调用构造函数。而是使用 React 组件生命周期方法 componentDidMount 来启动 api 调用。此外,我还使用了一个变量 (self) 来保存对组件 (this) 的引用,因此我可以在 axios promise 处理程序中使用它。
好的,我进入了解决方案:路由呈现一个函数,我在其中呈现组件并使用我需要的道具加载它。
this.RenderDetectorDetail = (props) => {
return (
<DetectorDetail detectors={this.props.detectors}/>
);
};
<Route exact path='/frontend/Detectors' render={this.RenderDetectorList} />