iT邦幫忙

第 12 屆 iThome 鐵人賽

DAY 28
0
Modern Web

為期 30 天的 react 大冒險系列 第 28

react 大冒險-render props-day 23

  • 分享至 

  • xImage
  •  

繼 higher-order-component 後,今天來說明 react 中另個概念 render-props
所謂的 render-props 就是在 component 之間 share 的 prop 本身的值是 function

達成在 React Component 之間共享 code 的方法

一樣從 HOC 該篇 的 ClickCounter 跟 HoverCounter 開始

這時候發現兩個 component 中的 incrementCount 跟 updateTimes 高度重複
把 constructor 跟 incrementCount 抽出來,新增一個 Counter.js

但是 Counter return 的內容是 一個 render prop
Counter 的 render prop 分成兩部分 this.state.count , this.incrementCount

import { Component } from "react";
class Counter extends Component {
	constructor(props) {
		super(props);
		this.state = {
			count: 0,
		};
		this.incrementCount = this.incrementCount.bind(this);
	}
	incrementCount() {
		this.setState((state) => {
			return { count: state.count + 1 };
		});
	}
	render() {
		const { count } = this.state;
		return <>{this.props.render(this.state.count, this.incrementCount)}</>;
	}
}

export default Counter;

回到 App.js,引入 Counter
這時候 pass in Counter 的 render prop 會是 function

import { Component } from "react";

import Counter from './Counter';
import ClickCounter from "./ClickCounter";

class App extends React.Component{
    render(){
        return(<Counter render={( count , incrementCount)=>(<ClickCounter count={count} incrementCount={incrementCount}/>)}/>)
    }
}

最後回到 ClickCounter.js
把 render 內的 state 都改為 prop (ClickCounter僅接受 prop,不再有 state)

import React from "react";

class ClickCounter extends React.Component {
	render() {
		const { count, incrementCount } = this.props;
		return (
			<div>
				<button onClick={incrementCount}>click {count} times</button>
			</div>
		);
	}
}

export default ClickCounter;

上一篇
react 大冒險-conditional rendering-day 22
下一篇
react 大冒險-setTimeout setInterval in react -day 24
系列文
為期 30 天的 react 大冒險30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言