什么是React函数作为子组件(React functions As Children)

React

函数作为子组件是一种模式,允许你将渲染函数作为 Children 属性传递给组件,以便您可以更改可以作为子组件传递给组件的内容。


使用

当你使用 Function 作为子组件时,可以将子组件指定为函数,而不是传递 JSX 标记。

1// index.tsx
2    <Foo>
3        {(name) => <div>`hello from ${name}`</div>}
4    </Foo>

Foo组件应该长这样

1// Foo.tsx
2    const Foo = ({ children }) => {
3        return children('foo')
4    }

例子

将函数作为子组件的高级示例。

1// PageWidth.tsx
2import React from 'react'
3
4class PageWidth extends React.Component {
5  state = { width: 0 }
6
7  componentDidMount() {
8    this.setState({ width: window.innerWidth })
9
10    window.addEventListener(
11      'resize',
12      ({ target }) => {
13        this.setState({ width: target.innerWidth })
14      }
15    )
16  }
17
18  render() {
19    const { width } = this.state
20    //渲染传过来的函数
21    return this.props.children(width)
22  }
23}

使用方式

1// index.tsx
2    <PageWidth>
3        {(width) => <div>{width}</div>}
4    </PageWidth>

正如在上面所看到的,children 被“重载”并作为函数传递给 PageWidth ,而不是按照自然的方式传递给 ReactNodeListPageWidth 组件的 render 方法调用 this.props.children (传递宽度),该方法返回渲染的 JSX。 在此示例中可以看到渲染回调的真正威力。 PageWidth 将完成所有繁重的工作,而渲染的具体内容可能会发生变化,具体取决于传递的渲染函数。


其他使用方式

点击展开/折叠
1//HTTPPOST.tsx
2import { Component, ReactNode } from 'react';
3import axios, { AxiosResponse } from 'axios';
4
5interface Props<T> {
6	url: string;//url
7	condition: unknown;//参数
8	loading?: ReactNode;//loading
9	children: (data: T) => ReactNode;//渲染组件
10	dataOperate: (data: T) => T;//数据处理
11	error?: ReactNode;//错误渲染
12}
13
14interface State<T> {
15	data: T;
16	component: ReactNode;
17}
18
19export default class POST<T> extends Component<Props<T>, State<T>> {
20	state: State<T> = {
21		data: {} as T,
22		component: this.props.loading || '',
23	};
24	async componentDidMount() {
25		const { url, error, condition, children, dataOperate } = this.props;
26		try {
27			const result: AxiosResponse<T> = await axios.post(url, condition);
28			const processedData: T = dataOperate(result.data);
29			this.setState({
30				data: processedData,
31				component: children(processedData),
32			});
33		} catch (e) {
34			this.setState({ component: error || 'error' });
35			throw e;
36		}
37	}
38	render() {
39		return this.state.component;
40	}
41}

使用

1const props = {
2    url: '123321',
3    condition: {},
4    loading: <span>loading 一下</span>,
5    dataOperate: (data) => {
6        return data.sort((a, b) => a - b);
7    },
8    error: <span>出错了!</span>,
9}
10 <HTTPPOST {...props}>
11            {
12                (data) => {
13                    return data.map(item => {
14                        <span>{item}</span>
15                    })
16                }
17            }
18</HTTPPOST>

转译自 reactpatterns../../../src/components/Tag