React无状态Wrap函数转带状态组件及children未定义报错解决
问题修复方案
报错原因
- 第9行
'children' is not defined:类组件语法使用错误,React 类组件继承Component时不能直接在后面的括号内解构参数,children是挂载在类组件实例this.props上的属性,你未正确声明自然识别不到。 - 第77行
'Children' is not defined:变量未定义,一是拼写错误(需要从props取小写的children),二是大写开头的Children是React提供的操作子元素的工具类,你既没有导入也没有单独声明该变量。 - 额外隐含问题:你当前的写法无法将MainLayout内部的state传递给包裹的子组件,且Smartfolio中直接取
props.portfolio.id无法生效,因为Smartfolio本身没有接收这个属性。
修复后的代码
1. MainLayout.jsx
import React, { Component, Children } from 'react' import { Redirect } from 'react-router' import { Row, Col, Alert } from 'reactstrap' import PortfolioTitle from './components/sidemodules/PortfolioTitle'; import AppMenu from './components/menu/AppMenu'; const Api = require('./api/PortfolioApi') // 修复类组件定义语法 class MainLayout extends Component { constructor(props) { super(props) this.state = { portfolio: { id: this.getPortfolioId(props), }, redirect: null, errors: [] } } getPortfolioId(props) { try { return props.match.params.id } catch (error) { return null } } componentDidMount() { if (this.state.portfolio.id) { Api.getPortfolio(this.state.portfolio.id) .then(response => { const [error, data] = response if (error) { this.setState({ errors: data }) } else { this.setState({ portfolio: data, errors: [] }) } }) } } render() { const { redirect, portfolio, errors } = this.state // 从props中取children const { children } = this.props if (redirect) { return ( <Redirect to={redirect} /> ) } else { return ( <> <Row> {errors.length > 0 && <div> {errors.map((error, index) => <Alert color="danger" key={index}> {error} </Alert> )} </div> } <Col xl={3}> <PortfolioTitle portfolio={portfolio} /> </Col> <Col xl={9}> <AppMenu portfolio={portfolio} /> {/* 遍历子组件,注入portfolio状态 */} {Children.map(children, child => React.cloneElement(child, { portfolio }) )} </Col> </Row> </> ) } } } export default MainLayout
2. Smartfolio.jsx
import React from 'react' import MainLayout from './layouts/MainLayout'; import HistoricalRentability from './components/dashboard/HistoricalRentability' import PortfolioCompostition from './components/dashboard/PortfolioComposition'; function Smartfolio() { return ( <> <MainLayout> <HistoricalRentability /> {/* id后续可以在组件内部直接从props.portfolio.id取,不需要在这里传 */} <PortfolioCompostition /> </MainLayout> </> ) } export default Smartfolio
使用说明
修复完成后,你在HistoricalRentability、PortfolioCompostition组件内部,直接通过props.portfolio就能拿到MainLayout维护的portfolio状态,两个编译报错会直接消除,功能可以正常运行。
内容的提问来源于stack exchange,提问作者Diogo Wernik
相关产品推荐
相关产品推荐

