使用HOC返回的组件将属性传递给组件会导致错误

时间:2019-01-07 14:39:39

标签: javascript reactjs frontend

我有一个DataComponent组件,它是一个HOC:

const DataComponent = (ComposedComponent, url) => 
class DataComponent extends React.Component {
    constructor(props) {
        super(props);
        this.state = {
            data: [],
            loaded: false,
            loading: false
        };
    }

    componentWillMount() {
        this.setState({loading: true});
        fetch(url)
            .then(response => response.json())
            .then(data => this.setState({
                data,
                loading: false,
                loaded: true
            }));
    }

    render() {
        return(
            <div className="data-component">
                {(this.state.loading) ? 
                    <div>Loading</div> :
                    <ComposedComponent {...this.state}/>}
            </div>
        );
    }
}

然后,我使用RandomMeUsers来呈现该HOC(PeopleList是另一个组件):

const RandomMeUsers = DataComponent(PeopleList, `https://randomuser.me/api/?results=10`);

ReactDOM.render(<RandomMeUsers/>, document.getElementById("app"));

工作正常,然后将count属性传递给RandomMeUsers,如下所示:

const RandomMeUsers = ({count}) => DataComponent(PeopleList, `https://randomuser.me/api/?results=${count}`);

ReactDOM.render(<RandomMeUsers count={10}/>, document.getElementById("app"));

当我运行它时,浏览器向我发送此错误:

Warning: Functions are not valid as a React child. 
This may happen if you return a Component instead of  from render. 
Or maybe you meant to call this function rather than return it.
in RandomMeUsers

我的代码有什么问题?

2 个答案:

答案 0 :(得分:2)

@Treyco很好地解释了为什么出现此错误。作为他们答案的替代方法,您可以像这样使用counturl

const RandomMeUsers = DataComponent(
  PeopleList,
  "https://randomuser.me/api/?results="
);

并在您的HOC中:

fetch(`${url}${this.props.count}`)
    .then(response => response.json())
    ....

但是,如果您的url将来需要更多参数,则此逻辑将不太有用。因此,也许不用提取url作为HOC的参数,而是可以提取它并将其放入props逻辑中。这样,您可以在其他地方操纵url并将其作为道具传递。

答案 1 :(得分:1)

您将HOC的结果转换为箭头函数。此功能不会替代组件的行为并传递道具。

以下是一个丑陋的语法:

const RandomMeUsers = ({ count }) => DataComponent(PeopleList, `https://randomuser.me/api/?results=${count}`);
const RandomTenUsers = RandomMeUsers({ count: 10 })

ReactDOM.render(<RandomTenUsers />, document.getElementById("app"));

也许这种语法是正确的:

ReactDOM.render(RandomMeUsers({ count: 10 }), document.getElementById("app"));