Component
Component γ― React γ³γ³γγΌγγ³γοΏ½?εΊεΊγ―γ©γΉγ§γγγJavaScript οΏ½?γ―γ©γΉγ¨γγ¦οΏ½?οΏ½ηΎ©γγγ¦γγΎγγReact γ―ηΎε¨γ§γγ―γ©γΉγ³γ³γγΌγγ³γγγ΅γγΌγγγ¦γγΎγγγζ°γγγ³γΌγγ§οΏ½?δ½Ώη¨γ―ζ¨ε₯¨γγγΎγγγ
class Greeting extends Component {
render() {
return <h1>Hello, {this.props.name}!</h1>;
}
}- γͺγγ‘γ¬γ³γΉ
Componentcontextpropsrefsstateconstructor(props)componentDidCatch(error, info)componentDidMount()componentDidUpdate(prevProps, prevState, snapshot?)componentWillMount()componentWillReceiveProps(nextProps)componentWillUpdate(nextProps, nextState)componentWillUnmount()forceUpdate(callback?)getChildContext()getSnapshotBeforeUpdate(prevProps, prevState)render()setState(nextState, callback?)shouldComponentUpdate(nextProps, nextState, nextContext)UNSAFE_componentWillMount()UNSAFE_componentWillReceiveProps(nextProps, nextContext)UNSAFE_componentWillUpdate(nextProps, nextState)static childContextTypesstatic contextTypesstatic contextTypestatic defaultPropsstatic propTypesstatic getDerivedStateFromError(error)static getDerivedStateFromProps(props, state)
- δ½Ώη¨ζ³
- 代ζΏζ‘
- γ·γ³γγ«γͺγ³γ³γγΌγγ³γγγ―γ©γΉγγι’ζ°γΈη§»θ‘
- state γζγ€γ³γ³γγΌγγ³γγγ―γ©γΉγγι’ζ°γΈη§»θ‘
- γ©γ€γγ΅γ€γ―γ«γ‘γ½γγγζγ€γ³γ³γγΌγγ³γγγ―γ©γΉγγι’ζ°γΈη§»θ‘
- γ³γ³γγ―γΉγγζγ€γ³γ³γγΌγγ³γγγ―γ©γΉγγι’ζ°γΈη§»θ‘
γͺγγ‘γ¬γ³γΉ
Component
γ―γ©γΉγ¨γγ¦ React γ³γ³γγΌγγ³γγοΏ½?οΏ½ηΎ©γγγ«γ―γη΅γΏθΎΌγΏοΏ½? Component γ―γ©γΉγηΆζΏγγrender γ‘γ½γγγοΏ½?οΏ½ηΎ©γγΎγγ
import { Component } from 'react';
class Greeting extends Component {
render() {
return <h1>Hello, {this.props.name}!</h1>;
}
}render γ‘γ½γγοΏ½?γΏγεΏ
ι γ§γγδ»οΏ½?γ‘γ½γγγ―γͺγγ·γ§γ³γ§γγ
context
γ―γ©γΉγ³γ³γγΌγγ³γγ§γ―γ³γ³γγ―γΉγγ this.context οΏ½?ε½’γ§ε©η¨γ§γγΎγγγγγ―γstatic contextTypeοΌηΎθ‘ηοΌγΎγγ― static contextTypesοΌιζ¨ε₯¨οΌγδ½Ώη¨γγ¦εγεγγγγ³γ³γγ―γΉγγζοΏ½?οΏ½γγε ΄εγ«οΏ½?γΏε©η¨γ§γγΎγγ
γ―γ©γΉγ³γ³γγΌγγ³γγ―γδΈεΊ¦γ« 1 οΏ½?ι‘οΏ½?γ³γ³γγ―γΉγγγθͺγΏεγγγ¨γγ§γγΎγγγ
class Button extends Component {
static contextType = ThemeContext;
render() {
const theme = this.context;
const className = 'button-' + theme;
return (
<button className={className}>
{this.props.children}
</button>
);
}
}props
γ―γ©γΉγ³γ³γγΌγγ³γγ«ζΈ‘γγγ props γ― this.props οΏ½?ε½’γ§ε©η¨γ§γγΎγγ
class Greeting extends Component {
render() {
return <h1>Hello, {this.props.name}!</h1>;
}
}
<Greeting name="Taylor" />refs
γοΏ½?γ³γ³γγΌγγ³γοΏ½?γ¬γ¬γ·γΌγͺζεεε½’εΌ ref γ«γ’γ―γ»γΉγ§γγΎγγ
state
γ―γ©γΉγ³γ³γγΌγγ³γοΏ½? state γ― this.state οΏ½?ε½’γ§ε©η¨γ§γγΎγγstate γγ£γΌγ«γγ―γͺγγΈγ§γ―γγ§γͺγγγ°γͺγγΎγγγstate γη΄ζ₯ζΈγζγγ¦γ―γγγΎγγγstate γε€ζ΄γγγε ΄εγ―γζ°γγ state γεΌζ°γ«γγ¦ setState γεΌγ³εΊγγΎγγ
class Counter extends Component {
state = {
age: 42,
};
handleAgeChange = () => {
this.setState({
age: this.state.age + 1
});
};
render() {
return (
<>
<button onClick={this.handleAgeChange}>
Increment age
</button>
<p>You are {this.state.age}.</p>
</>
);
}
}constructor(props)
γ³γ³γΉγγ©γ―γΏγ―γγ―γ©γΉγ³γ³γγΌγγ³γγγγ¦γ³γοΌη»ι’γ«θΏ½ε οΌγγγεγ«οΏ½?οΏ½θ‘γγγΎγγιεΈΈ React γ§γ―γγ³γ³γΉγγ©γ―γΏγ― 2 γ€οΏ½?οΏ½?ηγ§οΏ½?γΏε©η¨γγγΎγγstate οΏ½?οΏ½?οΏ½θ¨γ¨γγ―γ©γΉγ‘γ½γγοΏ½?γ―γ©γΉγ€γ³γΉγΏγ³γΉγΈοΏ½?γγ€γ³γγ§γγ
class Counter extends Component {
constructor(props) {
super(props);
this.state = { counter: 0 };
this.handleClick = this.handleClick.bind(this);
}
handleClick() {
// ...
}γ’γγ³γͺ JavaScript ζ§ζγδ½Ώη¨γγ¦γγε ΄εγγ³γ³γΉγγ©γ―γΏγ―γ»γ¨γγ©εΏ θ¦γγγΎγγγ代γγγ«δΈθ¨οΏ½?γ³γΌγγ―γγ’γγ³γγ©γ¦γΆγ Babel γͺγ©οΏ½?γγΌγ«γ§γ΅γγΌγγγγ¦γγγγγͺγγ―γ―γ©γΉγγ£γΌγ«γζ§ζγδ½Ώη¨γγ¦ζΈγη΄γγγ¨γγ§γγΎγγ
class Counter extends Component {
state = { counter: 0 };
handleClick = () => {
// ...
}γ³γ³γΉγγ©γ―γΏγ«γ―ε―δ½η¨γγ΅γγΉγ―γͺγγ·γ§γ³οΌsubscription, γ€γγ³γη»ι²γε€ι¨γγΌγΏθ³ΌθͺοΌγδΈεε«γγ¦γ―γγγΎγγγ
εΌζ°
props: γ³γ³γγΌγγ³γοΏ½?εζ propsγ
θΏγε€
constructor γ―δ½γθΏγγ¦γ―γγγΎγγγ
注ζηΉ
-
γ³γ³γΉγγ©γ―γΏε γ§ε―δ½η¨γγ΅γγΉγ―γͺγγ·γ§γ³γοΏ½?οΏ½θ‘γγͺγγ§γγ γγγ代γγγ«
componentDidMountγδ½Ώη¨γγ¦γγ γγγ -
γ³γ³γΉγγ©γ―γΏε γ§γ―γδ»οΏ½?γγΉγ¦οΏ½?γΉγγΌγγ‘γ³γοΏ½?εγ«
super(props)γεΌγ³εΊγεΏ θ¦γγγγΎγγγγγθ‘γγͺγγ¨γγ³γ³γΉγγ©γ―γΏγοΏ½?οΏ½θ‘γγγ¦γγιthis.propsγundefinedγ«γͺγγγγζ··δΉ±γζγγγ°οΏ½?εε γ¨γͺγε―θ½ζ§γγγγΎγγ -
this.stateγη΄ζ₯γ»γγγγ¦θ―γε―δΈοΏ½?ε ΄ζγγ³γ³γΉγγ©γ―γΏγ§γγδ»οΏ½?γγΉγ¦οΏ½?γ‘γ½γγε γ§γ―γ代γγγ«this.setState()γδ½Ώη¨γγεΏ θ¦γγγγΎγγγ³γ³γΉγγ©γ―γΏε γ§setStateγεΌγ³εΊγγͺγγ§γγ γγγ -
γ΅γΌγγ¬γ³γγͺγ³γ°γδ½Ώη¨γγε ΄εγγ³γ³γΉγγ©γ―γΏγγ΅γΌγδΈγ§οΏ½?οΏ½θ‘γγγγοΏ½?εΎγ«
renderγ‘γ½γγγηΆγγΎγγγγ γγcomponentDidMountγcomponentWillUnmountοΏ½?γγγͺγ©γ€γγ΅γ€γ―γ«γ‘γ½γγγ―γ΅γΌγδΈγ§γ―οΏ½?οΏ½θ‘γγγΎγγγ -
Strict Mode γζεΉοΏ½?ε ΄εγReact γ―ιηΊη°ε’γ«γγγ¦
constructorγ 2 εεΌγ³εΊγγ2 γ€οΏ½?γ€γ³γΉγΏγ³γΉοΏ½?γγ‘ 1 γ€γη ΄ζ£γγΎγγγγγ«γγγconstructorε€γ«η§»εγγγΉγεΆηΊηγͺε―δ½η¨γ«ζ°γ₯γγγγγͺγγΎγγ
componentDidCatch(error, info)
componentDidCatch γοΏ½?οΏ½ηΎ©γγγ¨γεγ³γ³γγΌγγ³γοΌι γοΏ½?εγε«γοΌγγ¬γ³γγΌδΈγ«γ¨γ©γΌγγΉγγΌγγγ¨γγ« React γγγγεΌγ³εΊγγΎγγγγγ«γγγζ¬ηͺη°ε’γ§γοΏ½?γ¨γ©γΌγγ¨γ©γΌγ¬γγΌγγ΅γΌγγΉγ«γγ°γ¨γγ¦θ¨ι²γγγγ¨γγ§γγΎγγ
ιεΈΈγγγ―γγ¨γ©γΌγ«εεΏγγ¦ state γζ΄ζ°γγγ¦γΌγΆγ«γ¨γ©γΌγ‘γγ»γΌγΈγ葨瀺γγγγοΏ½? static getDerivedStateFromError γ¨δΈη·γ«δ½Ώη¨γγγΎγγγγγοΏ½?γ‘γ½γγγζγ€γ³γ³γγΌγγ³γοΏ½?γγ¨γγ¨γ©γΌγγ¦γ³γγͺ (error boundary) γ¨εΌγ³γΎγγ
εΌζ°
-
error: γΉγγΌγγγγ¨γ©γΌγηΎοΏ½?οΏ½ηγ«γ―ιεΈΈErrorοΏ½?γ€γ³γΉγΏγ³γΉγ«γͺγγΎγγγγοΏ½?γγ¨γ―δΏθ¨Όγγγ¦γγΎγγγJavaScript γ§γ―ζεεγnullγγε«γγδ»»ζοΏ½?ε€γthrowγγγγ¨γ許γγγ¦γγγγγ§γγ -
info: γ¨γ©γΌγ«ι’γγθΏ½ε ζ ε ±γε«γγͺγγΈγ§γ―γγγοΏ½?componentStackγγ£γΌγ«γγ«γ―γγΉγγΌγγγ³γ³γγΌγγ³γγ¨γοΏ½?γγΉγ¦οΏ½?θ¦ͺγ³γ³γγΌγγ³γοΏ½?εεγγγ³γ½γΌγΉδΈοΏ½?δ½οΏ½?γε«γγ γΉγΏγγ―γγ¬γΌγΉγε«γΎγγΎγγζ¬ηͺη°ε’γ§γ―γγ³γ³γγΌγγ³γεγ―γγγγ‘γ€γγγ¦γγΎγγζ¬ηͺη°ε’η¨γ«γ¨γ©γΌγ¬γγΌγγθ¨οΏ½?οΏ½γγε ΄εγ―γιεΈΈοΏ½? JavaScript γ¨γ©γΌγΉγΏγγ―γ¨εγγγγ«γγ½γΌγΉγγγγδ½Ώη¨γγ¦γ³γ³γγΌγγ³γγΉγΏγγ―γγγ³γΌγγ§γγΎγγ
θΏγε€
componentDidCatch γ―δ½γθΏγγ¦γ―γγγΎγγγ
注ζηΉ
-
δ»₯εγ―γUI γζ΄ζ°γγ¦γγ©γΌγ«γγγ―οΏ½?γ¨γ©γΌγ‘γγ»γΌγΈγ葨瀺γγγγγ«
componentDidCatchε γ§setStateγεΌγ³εΊγγγ¨γδΈθ¬ηγ§γγγγγγ―ιζ¨ε₯¨γ¨γͺγγ代γγγ«static getDerivedStateFromErrorγοΏ½?οΏ½ηΎ©γγγγ¨γζ¨ε₯¨γγγ¦γγΎγγ -
React οΏ½?ζ¬ηͺη¨γγ«γγ¨ιηΊη¨γγ«γγ§γ―γ
componentDidCatchγγ¨γ©γΌγε¦ηγγζΉζ³γγγγγ«η°γͺγγΎγγιηΊδΈγ―γγ¨γ©γΌγwindowγ«γΎγ§γγγ«γ’γγγγγγγwindow.onerrorγwindow.addEventListener('error', callback)γ¨γγ£γγ³γΌγγcomponentDidCatchγ«γγ£γ¦γγ£γγγγγγ¨γ©γΌγζγΎγγγγ¨γγ§γγΎγγδΈζΉγ§ζ¬ηͺη°ε’γ§γ―γ¨γ©γΌγ―γγγ«γ’γγγγͺγγγγη₯ε οΏ½?γ¨γ©γΌγγ³γγ©γ―componentDidCatchγ«γγ£γ¦ζη€Ίηγ«γγ£γγγγγͺγγ£γγ¨γ©γΌοΏ½?γΏγεγεγγΎγγ
componentDidMount()
componentDidMount γ‘γ½γγγοΏ½?οΏ½ηΎ©γγγ¨γγ³γ³γγΌγγ³γγη»ι’γ«θΏ½ε οΌγγ¦γ³γοΌγγγγ¨γγ« React γγγγεΌγ³εΊγγΎγγδΈθ¬ηγ«γ―γγγ§γγγΌγΏεεΎγγ΅γγΉγ―γͺγγ·γ§γ³θ¨οΏ½?οΏ½γ DOM γγΌγοΏ½?ζδ½γιε§γγΎγγ
componentDidMount γοΏ½?οΏ½θ£
γγε ΄εγιεΈΈγ―γγ°γιΏγγγγγ«δ»οΏ½?γ©γ€γγ΅γ€γ―γ«γ‘γ½γγγοΏ½?οΏ½θ£
γγεΏ
θ¦γγγγΎγγδΎγγ°γcomponentDidMount γδ½γγοΏ½? state γ props γθͺγΏεγε ΄εγ―γγγγ«ε€ζ΄γγγ£γε ΄εγ«ε¦ηγγγγγ« componentDidUpdate γοΏ½?οΏ½θ£
γγεΏ
θ¦γγγγcomponentDidMount γοΏ½?οΏ½θ‘γγγγ¨γγ―γͺγΌγ³γ’γγγγγγγ«γ― componentWillUnmount γοΏ½?οΏ½θ£
γγεΏ
θ¦γγγγΎγγ
class ChatRoom extends Component {
state = {
serverUrl: 'https://localhost:1234'
};
componentDidMount() {
this.setupConnection();
}
componentDidUpdate(prevProps, prevState) {
if (
this.props.roomId !== prevProps.roomId ||
this.state.serverUrl !== prevState.serverUrl
) {
this.destroyConnection();
this.setupConnection();
}
}
componentWillUnmount() {
this.destroyConnection();
}
// ...
}εΌζ°
componentDidMount γ―εΌζ°γεγεγγΎγγγ
θΏγε€
componentDidMount γ―δ½γθΏγγ¦γ―γγγΎγγγ
注ζηΉ
-
Strict Mode γγͺγ³οΏ½?ε ΄εγReact γ―ιηΊδΈγ«
componentDidMountγεΌγ³εΊγγη΄εΎγ«componentWillUnmountγεΌγ³εΊγγγγγ¦εεΊ¦componentDidMountγεΌγ³εΊγγΎγγγγγ«γγγcomponentWillUnmountοΏ½?οΏ½?οΏ½θ£ γεΏγγε ΄εγγγοΏ½?γγΈγγ―γcomponentDidMountοΏ½?ζεγ¨ζ£γγγι‘οΏ½?γγγ«ε―ΎεΏγγγ¦γγͺγε ΄εγ«ζ°γ₯γγγγγͺγγΎγγ -
componentDidMountοΏ½?δΈγ§η΄γ‘γ«setStateγεΌγ³εΊγγγ¨γ―ε―θ½γ§γγγε―θ½γͺιγιΏγγγΉγγ§γγγγγ―θΏ½ε οΏ½?γ¬γ³γγΌγεΌγθ΅·γγγΎγγγγγ©γ¦γΆγη»ι’γζ΄ζ°γγεγ«ηΊηγγΎγγγοΏ½?γγγγοΏ½?γ±γΌγΉγ§γ―renderγ 2 εεΌγ³εΊγγγ―γγΎγγγγ¦γΌγΆγ―δΈιεη«―γͺ state γθ¦γγ«ζΈγΏγΎγγγοΏ½?γγΏγΌγ³γ―γγ°γγ°γγγ©γΌγγ³γΉοΏ½?ει‘γεΌγθ΅·γγγγγ注ζγγ¦δ½Ώη¨γγ¦γγ γγγγ»γ¨γγ©οΏ½?ε ΄εγεζ state γconstructorγ§δ»£ε ₯γ§γγγ―γγ§γγγγ γγγ’γΌγγ«γγγΌγ«γγγοΏ½?γγγͺε ΄εγ―γδ½γγοΏ½? DOM γγΌγοΏ½?δ½οΏ½?γγ΅γ€γΊγ«δΎεγγθ¦η΄ γγ¬γ³γγΌγγοΏ½?γ« DOM γγΌγοΏ½?ζΈ¬οΏ½?οΏ½γθ‘γγγγγγγεΏ θ¦γ«γͺγγγ¨γγγγΎγγ
componentDidUpdate(prevProps, prevState, snapshot?)
componentDidUpdate γ‘γ½γγγοΏ½?οΏ½ηΎ©γγγ¨γγ³γ³γγΌγγ³γγζ΄ζ°εΎοΏ½? props γ state γ§εγ¬γ³γγΌγγγη΄εΎγ« React γγγγεΌγ³εΊγγΎγγγοΏ½?γ‘γ½γγγ―εεγ¬γ³γγΌγ§γ―εΌγ³εΊγγγΎγγγ
ζ΄ζ°εΎγ« DOM γζδ½γγγγγ«γγγδ½Ώη¨γγγγ¨γγ§γγΎγγγγγ―γΎγγγγγγ―γΌγ―γͺγ―γ¨γΉγγθ‘γδΈθ¬ηγͺε ΄ζγ§γγγγΎγγγηΎε¨οΏ½? props γεοΏ½? props γ¨ζ―θΌγγεΏ
θ¦γγγγΎγοΌδΎγγ° props γε€ζ΄γγγ¦γγͺγε ΄εγζ°γγγγγγ―γΌγ―γͺγ―γ¨γΉγγ―εΏ
θ¦γͺγγγγγγΎγγοΌγιεΈΈγcomponentDidMount γ componentWillUnmount γ¨δΈη·γ«δ½Ώη¨γγΎγγ
class ChatRoom extends Component {
state = {
serverUrl: 'https://localhost:1234'
};
componentDidMount() {
this.setupConnection();
}
componentDidUpdate(prevProps, prevState) {
if (
this.props.roomId !== prevProps.roomId ||
this.state.serverUrl !== prevState.serverUrl
) {
this.destroyConnection();
this.setupConnection();
}
}
componentWillUnmount() {
this.destroyConnection();
}
// ...
}εΌζ°
-
prevProps: ζ΄ζ°εοΏ½? propsγprevPropsγ¨this.propsγζ―θΌγγ¦δ½γε€γγ£γγγε€ζγγΎγγ -
prevState: ζ΄ζ°εοΏ½? stateγprevStateγ¨this.stateγζ―θΌγγ¦δ½γε€γγ£γγγε€ζγγΎγγ -
snapshot:getSnapshotBeforeUpdateγοΏ½?οΏ½θ£ γγε ΄εγsnapshotγ«γ―γοΏ½?γ‘γ½γγγγθΏγγγε€γε«γΎγγΎγγγγδ»₯ε€οΏ½?ε ΄εγ―undefinedγ«γͺγγΎγγ
θΏγε€
componentDidUpdate γ―δ½γθΏγγ¦γ―γγγΎγγγ
注ζηΉ
-
shouldComponentUpdateγοΏ½?οΏ½ηΎ©γγγ¦γγγγγγfalseγθΏγε ΄εγcomponentDidUpdateγ―εΌγ³εΊγγγΎγγγ -
componentDidUpdateε οΏ½?γγΈγγ―γ―ιεΈΈγthis.propsγ¨prevPropsγthis.stateγ¨prevStateγζ―θΌγγζ‘δ»Άζγ§γ©γγγγεΏ θ¦γγγγΎγγγγγ§γͺγγγ°γη‘ιγ«γΌγγδ½γεΊγγͺγΉγ―γγγγΎγγ -
componentDidUpdateοΏ½?δΈγ§η΄γ‘γ«setStateγεΌγ³εΊγγγ¨γ―ε―θ½γ§γγγε―θ½γͺιγιΏγγγΉγγ§γγγγγ―θΏ½ε οΏ½?γ¬γ³γγΌγεΌγθ΅·γγγΎγγγγγ©γ¦γΆγη»ι’γζ΄ζ°γγεγ«ηΊηγγΎγγγοΏ½?γγγγοΏ½?γ±γΌγΉγ§γ―renderγ 2 εεΌγ³εΊγγγ―γγΎγγγγ¦γΌγΆγ―δΈιεη«―γͺ state γθ¦γγ«ζΈγΏγΎγγγοΏ½?γγΏγΌγ³γ―γγ°γγ°γγγ©γΌγγ³γΉοΏ½?ει‘γεΌγθ΅·γγγΎγγγγ γγγ’γΌγγ«γγγΌγ«γγγοΏ½?γγγͺγ¬γ’γͺγ±γΌγΉγ§γ―γδ½γγοΏ½? DOM γγΌγοΏ½?δ½οΏ½?γγ΅γ€γΊγ«δΎεγγθ¦η΄ γγ¬γ³γγΌγγοΏ½?γ« DOM γγΌγοΏ½?ζΈ¬οΏ½?οΏ½γθ‘γγγγγγγεΏ θ¦γ«γͺγγγ¨γγγγΎγγ
componentWillMount()
componentWillReceiveProps(nextProps)
componentWillUpdate(nextProps, nextState)
componentWillUnmount()
componentWillUnmount γ‘γ½γγγοΏ½?οΏ½ηΎ©γγγ¨γReact γ―γ³γ³γγΌγγ³γγη»ι’γγει€οΌγ’γ³γγ¦γ³γοΌγγγεγ«γγγεΌγ³εΊγγΎγγγγγγγΌγΏοΏ½?εεΎγγγ£γ³γ»γ«γγγγγ΅γγΉγ―γͺγγ·γ§γ³γει€γγοΏ½?γ«δΈθ¬ηγͺε ΄ζγ§γγ
componentWillUnmount ε
οΏ½?γγΈγγ―γ― componentDidMount ε
οΏ½?γγΈγγ―γ¨γι‘οΏ½?γγγ«ε―ΎεΏγγγγΉγγ§γγδΎγγ°γcomponentDidMount γγ΅γγΉγ―γͺγγ·γ§γ³οΏ½?θ¨οΏ½?οΏ½γθ‘γε ΄εγcomponentWillUnmount γ―γοΏ½?γ΅γγΉγ―γͺγγ·γ§γ³γγ―γͺγΌγ³γ’γγγγγΉγγ§γγcomponentWillUnmount οΏ½?γ―γͺγΌγ³γ’γγγγΈγγ―γ props γ state γθͺγΏεγε ΄εγιεΈΈγ―ε€γ props γ¨ state γ«ε―ΎεΏγγγͺγ½γΌγΉοΌγ΅γγΉγ―γͺγγ·γ§γ³γͺγ©οΌγγ―γͺγΌγ³γ’γγγγγγγ« componentDidUpdate γοΏ½?οΏ½θ£
γγεΏ
θ¦γγγγΎγγ
class ChatRoom extends Component {
state = {
serverUrl: 'https://localhost:1234'
};
componentDidMount() {
this.setupConnection();
}
componentDidUpdate(prevProps, prevState) {
if (
this.props.roomId !== prevProps.roomId ||
this.state.serverUrl !== prevState.serverUrl
) {
this.destroyConnection();
this.setupConnection();
}
}
componentWillUnmount() {
this.destroyConnection();
}
// ...
}εΌζ°
componentWillUnmount γ―εΌζ°γεγεγγΎγγγ
θΏγε€
componentWillUnmount γ―δ½γθΏγγ¦γ―γγγΎγγγ
注ζηΉ
- Strict Mode γγͺγ³οΏ½?ε ΄εγReact γ―ιηΊδΈγ«
componentDidMountγεΌγ³εΊγγη΄εΎγ«componentWillUnmountγεΌγ³εΊγγγγγ¦εεΊ¦componentDidMountγεΌγ³εΊγγΎγγγγγ«γγγcomponentWillUnmountοΏ½?οΏ½?οΏ½θ£ γεΏγγε ΄εγγγοΏ½?γγΈγγ―γcomponentDidMountοΏ½?ζεγ¨ζ£γγγι‘οΏ½?γγγ«ε―ΎεΏγγγ¦γγͺγε ΄εγ«ζ°γ₯γγγγγͺγγΎγγ
forceUpdate(callback?)
γ³γ³γγΌγγ³γγεΌ·εΆηγ«εγ¬γ³γγΌγγΎγγ
ιεΈΈγγγγ―εΏ
θ¦γγγΎγγγγ³γ³γγΌγγ³γοΏ½? render γ‘γ½γγγ this.propsγthis.state γγγ³ this.context γγοΏ½?γΏθͺγΏεγγθ‘γε ΄εγγ³γ³γγΌγγ³γε
γΎγγ―γοΏ½?θ¦ͺγ§ setState γεΌγ³εΊγγγγ¨θͺεηγ«εγ¬γ³γγΌγηΊηγγΎγγγγγγγ³γ³γγΌγγ³γοΏ½? render γ‘γ½γγγε€ι¨γγΌγΏγ½γΌγΉγγη΄ζ₯θͺγΏεγγθ‘γ£γ¦γγε ΄εγγοΏ½?γγΌγΏγ½γΌγΉγε€ζ΄γγγγ¨γγ« React γ«γ¦γΌγΆγ€γ³γΏγΌγγ§γΌγΉγζ΄ζ°γγγγγ«ζη€ΊγγεΏ
θ¦γγγγΎγγforceUpdate γ―γγγθ‘γγγγγ«γγγγοΏ½?γοΏ½?γ§γγ
γγγγ forceUpdate οΏ½?δ½Ώη¨γ―ιΏγγrender ε
γ§γ― this.props γ¨ this.state γγοΏ½?γΏθͺγΏεγγγγ«γγ¦γγ γγγ
εΌζ°
- ηη₯ε―θ½
callback: ζοΏ½?οΏ½γγγε ΄εγReact γ―ζ΄ζ°γγ³γγγγγγεΎγ«γζΈ‘γγγcallbackγεΌγ³εΊγγΎγγ
θΏγε€
forceUpdate γ―δ½γθΏγγΎγγγ
注ζηΉ
forceUpdateγεΌγ³εΊγγ¨γReact γ―shouldComponentUpdateγεΌγ³εΊγγγ«εγ¬γ³γγΌγγΎγγ
getChildContext()
γοΏ½?γ³γ³γγΌγγ³γγζδΎγγγ¬γ¬γ·γΌγ³γ³γγ―γΉγοΏ½?ε€γζοΏ½?οΏ½γγΎγγ
getSnapshotBeforeUpdate(prevProps, prevState)
getSnapshotBeforeUpdate γοΏ½?οΏ½θ£
γγγ¨γReact γ― DOM γζ΄ζ°γγη΄εγ«γγγεΌγ³εΊγγΎγγγγγ«γγγγ³γ³γγΌγγ³γγ― DOM γγζ
ε ±οΌδΎγγ°γΉγ―γγΌγ«δ½οΏ½?οΌγεεΎγγγγ¨γγ§γγΎγγγοΏ½?γ©γ€γγ΅γ€γ―γ«γ‘γ½γγγθΏγγγγγε€γ―γcomponentDidUpdate γ«εΌζ°γ¨γγ¦ζΈ‘γγγΎγγ
δΎγγ°γζ΄ζ°ιγ§γΉγ―γγΌγ«δ½οΏ½?γδΏζγγεΏ θ¦γγγγγ£γγγΉγ¬γγοΏ½?γγγͺ UI γ§γγγδ½Ώη¨γγγγ¨γγ§γγΎγγ
class ScrollingList extends React.Component {
constructor(props) {
super(props);
this.listRef = React.createRef();
}
getSnapshotBeforeUpdate(prevProps, prevState) {
// Are we adding new items to the list?
// Capture the scroll position so we can adjust scroll later.
if (prevProps.list.length < this.props.list.length) {
const list = this.listRef.current;
return list.scrollHeight - list.scrollTop;
}
return null;
}
componentDidUpdate(prevProps, prevState, snapshot) {
// If we have a snapshot value, we've just added new items.
// Adjust scroll so these new items don't push the old ones out of view.
// (snapshot here is the value returned from getSnapshotBeforeUpdate)
if (snapshot !== null) {
const list = this.listRef.current;
list.scrollTop = list.scrollHeight - snapshot;
}
}
render() {
return (
<div ref={this.listRef}>{/* ...contents... */}</div>
);
}
}δΈθ¨οΏ½?δΎγ§γ―γgetSnapshotBeforeUpdate γ§η΄ζ₯ scrollHeight γγγγγ£γθͺγΏεγγγ¨γιθ¦γ§γγrenderγUNSAFE_componentWillReceivePropsγγΎγγ― UNSAFE_componentWillUpdate γ§θͺγΏεγγγ¨γ―οΏ½?οΏ½ε
¨γ§γ―γγγΎγγγγγγοΏ½?γ‘γ½γγγεΌγ³εΊγγγ¦γγ React γ DOM γζ΄ζ°γγγΎγ§γ«ζιοΏ½?γγγε―θ½ζ§γγγγγγ§γγ
εΌζ°
-
prevProps: ζ΄ζ°εοΏ½? propsγprevPropsγ¨this.propsγζ―θΌγγ¦δ½γε€γγ£γγγε€ζγγΎγγ -
prevState: ζ΄ζ°εοΏ½? stateγprevStateγ¨this.stateγζ―θΌγγ¦δ½γε€γγ£γγγε€ζγγΎγγ
θΏγε€
δ»»ζοΏ½?εοΏ½?γΉγγγγ·γ§γγε€γγΎγγ― null γθΏγγ¦γγ γγγθΏγγε€γ―γcomponentDidUpdate οΏ½?第 3 εΌζ°γ¨γγ¦ζΈ‘γγγΎγγ
注ζηΉ
shouldComponentUpdateγοΏ½?οΏ½ηΎ©γγγ¦γγγfalseγθΏγε ΄εγgetSnapshotBeforeUpdateγ―εΌγ³εΊγγγΎγγγ
render()
render γ‘γ½γγγ―γγ―γ©γΉγ³γ³γγΌγγ³γγ«γγγε―δΈοΏ½?εΏ
ι γ‘γ½γγγ§γγ
render γ‘γ½γγγ―γη»ι’γ«θ‘¨η€ΊγγγγοΏ½?γζοΏ½?οΏ½γγΎγγδΎγγ°οΌ
import { Component } from 'react';
class Greeting extends Component {
render() {
return <h1>Hello, {this.props.name}!</h1>;
}
}React γ―γγγγγΏγ€γγ³γ°γ§ render γεΌγ³εΊγε―θ½ζ§γγγγγγηΉοΏ½?οΏ½οΏ½?ζιγ«οΏ½?οΏ½θ‘γγγγγ¨γεζγ«γγ¦γ―γγγΎγγγιεΈΈγrender γ‘γ½γγγ― JSX γθΏγγΉγγ§γγγγγγ€γοΏ½?δ»οΏ½?εοΏ½?θΏγε€οΌζεεγͺγ©οΌγγ΅γγΌγγγγ¦γγΎγγθΏγγΉγ JSX γθ¨οΏ½?οΏ½γγγγγ«γrender γ‘γ½γγγ― this.propsγthis.stateγγγγ³ this.context γθͺγΏεγγγ¨γγ§γγΎγγ
render γ‘γ½γγγ―η΄ι’ζ°γ¨γγ¦ζΈγγΉγγ§γγγ€γΎγγpropsγstateγγ³γ³γγ―γΉγγεγγ§γγγ°εγη΅ζγθΏγγΉγγ§γγγΎγγε―δ½η¨οΌγ΅γγΉγ―γͺγγ·γ§γ³οΏ½?θ¨οΏ½?οΏ½γͺγ©οΌγε«γγ γγγγ©γ¦γΆοΏ½? API γ¨γγεγγγγγγγΉγγ§γ―γγγΎγγγε―δ½η¨γ―γγ€γγ³γγγ³γγ©γ componentDidMount οΏ½?γγγͺγ‘γ½γγε
γ§θ‘γγΉγγ§γγ
εΌζ°
render γ―εΌζ°γεγεγγΎγγγ
θΏγε€
render γ―γγγγζεΉγͺ React γγΌγγθΏγγγ¨γγ§γγΎγγγγγ«γ―γ<div /> οΏ½?γγγͺ React θ¦η΄ γζεεγζ°ε€γγγΌγΏγ«γη©ΊοΏ½?γγΌγοΌnullγundefinedγtrueγfalseοΌγγγγ³ React γγΌγοΏ½?ι
εγε«γΎγγΎγγ
注ζηΉ
-
renderγ― propsγstateγγ³γ³γγ―γΉγγ«ε―Ύγγη΄ι’ζ°γ¨γγ¦ζΈγγΉγγ§γγε―δ½η¨γζγ£γ¦γ―γγγΎγγγ -
shouldComponentUpdateγοΏ½?οΏ½ηΎ©γγγ¦γγfalseγθΏγε ΄εγrenderγ―εΌγ³εΊγγγΎγγγ -
Strict Mode γζεΉοΏ½?ε ΄εγReact γ―ιηΊδΈγ«
renderγ 2 εεΌγ³εΊγγγοΏ½?γγ‘οΏ½? 1 γ€οΏ½?η΅ζγη ΄ζ£γγΎγγγγγ«γγγrenderγ‘γ½γγοΏ½?ε€γ«η§»εγγγΉγεΆηΊηγͺε―δ½η¨γ«ζ°γ₯γγγγγͺγγΎγγ -
renderοΏ½?εΌγ³εΊγγ¨γοΏ½?εΎοΏ½?componentDidMountγcomponentDidUpdateοΏ½?εΌγ³εΊγγ¨οΏ½?ιγ«δΈε―ΎδΈοΏ½?ε―ΎεΏι’δΏγ―γγγΎγγγReact γεΏ θ¦γ¨ε€ζγγε ΄εγrenderοΏ½?εΌγ³εΊγη΅ζοΏ½?δΈι¨γ―η ΄ζ£γγγε―θ½ζ§γγγγΎγγ
setState(nextState, callback?)
setState οΏ½?εΌγ³εΊγγ― React γ³γ³γγΌγγ³γοΏ½? state οΏ½?ζ΄ζ°γθ‘γγΎγγ
class Form extends Component {
state = {
name: 'Taylor',
};
handleNameChange = (e) => {
const newName = e.target.value;
this.setState({
name: newName
});
}
render() {
return (
<>
<input value={this.state.name} onChange={this.handleNameChange} />
<p>Hello, {this.state.name}.</p>
</>
);
}
}setState γ―γ³γ³γγΌγγ³γοΏ½? state γΈοΏ½?ζ΄ζ°γγγ₯γΌγ«ε
₯γγΎγγγγγ―γγοΏ½?γ³γ³γγΌγγ³γγ¨γοΏ½?εγζ°γγ state γ§εγ¬γ³γγΌγγεΏ
θ¦γγγγγ¨γ React γ«δΌγγΎγγγγγγγ¦γΌγΆζδ½γ«ε―ΎεΏγγ¦γ¦γΌγΆγ€γ³γΏγΌγγ§γΌγΉγζ΄ζ°γγγγοΏ½?δΈ»θ¦γͺζΉζ³γ¨γͺγγΎγγ
γΎγγsetState γ«ι’ζ°γζΈ‘γγγ¨γγ§γγΎγγγγγ«γγγεοΏ½? state γ«εΊγ₯γγ¦ state γζ΄ζ°γγγγ¨γγ§γγΎγγ
handleIncreaseAge = () => {
this.setState(prevState => {
return {
age: prevState.age + 1
};
});
}γγγγεΏ θ¦γγγγγγ§γ―γγγΎγγγγεγγ€γγ³γδΈγ«θ€ζ°ε state γζ΄ζ°γγγε ΄εγ«γ―ζη¨γ§γγ
εΌζ°
-
nextStateοΌγͺγγΈγ§γ―γγΎγγ―ι’ζ°γnextStateγ¨γγ¦γͺγγΈγ§γ―γγζΈ‘γγ¨γγγγ―this.stateγ«ζ΅ γ (shallow) γγΌγΈγγγΎγγnextStateγ¨γγ¦ι’ζ°γζΈ‘γγ¨γγγγ―ζ΄ζ°η¨ι’ζ° (updater function) γ¨γγ¦ζ±γγγΎγγγοΏ½?ι’ζ°γ―η΄ι’ζ°γ§γͺγγγ°γͺγγγstate γ¨ props οΏ½?ηΎε¨ε€γεΌζ°γ¨γγ¦εγγthis.stateγ«ζ΅ γγγΌγΈγγγγγοΏ½?γͺγγΈγ§γ―γγθΏγγΎγγReact γ―γοΏ½?ζ΄ζ°η¨ι’ζ°γγγ₯γΌγ«ε ₯γγ¦γγγ³γ³γγΌγγ³γγεγ¬γ³γγΌγγΎγγ欑�?γ¬γ³γγΌδΈγ«γReact γ―εοΏ½? state γ«ε―Ύγγ¦γγ₯γΌγ«ε ₯γγγγγγΉγ¦οΏ½?ζ΄ζ°η¨ι’ζ°γι©η¨γγ欑εοΏ½? state γθ¨οΏ½?οΏ½γγΎγγ
-
ηη₯ε―θ½
callback: ζοΏ½?οΏ½γγγε ΄εγReact γ―ζ΄ζ°γγ³γγγγγγεΎγ«ζΈ‘γγγcallbackγεΌγ³εΊγγΎγγ
θΏγε€
setState γ―δ½γθΏγγΎγγγ
注ζηΉ
-
setStateγ―ε³ζηγͺγ³γ³γγΌγγ³γοΏ½?ζ΄ζ°ε½δ»€γ§γ―γͺγγγͺγ―γ¨γΉγγ γ¨θγγ¦γγ γγγθ€ζ°οΏ½?γ³γ³γγΌγγ³γγγ€γγ³γγ«εΏγγ¦ state γζ΄ζ°γγγ¨γγReact γ―γγγοΏ½?ζ΄ζ°γγγγοΌζγοΌε¦ηγγγ€γγ³γοΏ½?η΅δΊζγ« 1 εΊ¦γ γεγ¬γ³γγΌγγΎγγηΉοΏ½?οΏ½οΏ½? state ζ΄ζ°γεΌ·εΆηγ«εζηγ«ι©η¨γγεΏ θ¦γγγη¨γͺγ±γΌγΉγ§γ―γflushSyncγ§γ©γγγγγγ¨γγ§γγΎγγγγγγ―γγγ©γΌγγ³γΉγδ½δΈγγγε―θ½ζ§γγγγΎγγ -
setStateγ―this.stateγε³ζγ«ζ΄ζ°γγΎγγγγοΏ½?γγγsetStateγεΌγ³εΊγγη΄εΎγ«this.stateγθͺγΏεγγγ¨γ―ζ½ε¨ηγͺθ½γ¨γη©΄γ¨γͺγγΎγγ代γγγ«γcomponentDidUpdateγΎγγ― setState οΏ½?callbackεΌζ°γδ½Ώη¨γγ¦γγ γγγγ©γ‘γγζ΄ζ°γι©η¨γγγεΎγ«ηΊη«γγγγ¨γδΏθ¨Όγγγ¦γγΎγγεοΏ½? state γ«εΊγ₯γγ state γθ¨οΏ½?οΏ½γγεΏ θ¦γγγε ΄εγδΈθ¨γ§θͺ¬ζγγγγγ«nextStateγ¨γγ¦ι’ζ°γζΈ‘γγγ¨γγ§γγΎγγ
shouldComponentUpdate(nextProps, nextState, nextContext)
shouldComponentUpdate γοΏ½?οΏ½ηΎ©γγγ¨γReact γ―εγ¬γ³γγΌγγΉγγγγ§γγγγ©γγγε€ζγγγγγ«γγγεΌγ³εΊγγΎγγ
γγγζ¬ε½γ«ζεγ§ζΈγγγε ΄εγ―γthis.props γ¨ nextPropsγthis.state γ¨ nextState γζ―θΌγγδΈγ§ false γθΏγγγ¨γ§γζ΄ζ°γγΉγγγγ§γγγ¨ React γ«δΌγγγγ¨γγ§γγΎγγ
class Rectangle extends Component {
state = {
isHovered: false
};
shouldComponentUpdate(nextProps, nextState) {
if (
nextProps.position.x === this.props.position.x &&
nextProps.position.y === this.props.position.y &&
nextProps.size.width === this.props.size.width &&
nextProps.size.height === this.props.size.height &&
nextState.isHovered === this.state.isHovered
) {
// Nothing has changed, so a re-render is unnecessary
return false;
}
return true;
}
// ...
}ζ°γγ props γ state γεγεγιγ« React γ― shouldComponentUpdate γεΌγ³εΊγγΎγγγγγ©γ«γγ― true γ§γγγοΏ½?γ‘γ½γγγ―εεγ¬γ³γγΌοΏ½?ε ΄εγ¨ forceUpdate γδ½Ώη¨γγγε ΄εγ«γ―εΌγ³εΊγγγΎγγγ
εΌζ°
nextProps: γ³γ³γγΌγγ³γγγ¬γ³γγΌγγγγ¨γγ¦γγ欑�? propsγδ½γε€γγ£γγγε€ζγγγγγ«nextPropsγthis.propsγ¨ζ―θΌγγΎγγnextState: γ³γ³γγΌγγ³γγγ¬γ³γγΌγγγγ¨γγ¦γγ欑�? stateγδ½γε€γγ£γγγε€ζγγγγγ«nextStateγthis.stateγ¨ζ―θΌγγΎγγnextContext: γ³γ³γγΌγγ³γγγ¬γ³γγΌγγγγ¨γγ¦γγ欑�?γ³γ³γγ―γΉγγδ½γε€γγ£γγγε€ζγγγγγ«nextContextγthis.contextγ¨ζ―θΌγγΎγγstatic contextTypeοΌηΎθ‘ηοΌγΎγγ―static contextTypesοΌγ¬γ¬γ·γΌοΌγζοΏ½?οΏ½γγε ΄εοΏ½?γΏε©η¨ε―θ½γ§γγ
θΏγε€
γ³γ³γγΌγγ³γγεγ¬γ³γγΌγγγε ΄εγ― true γθΏγγΎγγγγγγγγ©γ«γοΏ½?ζεγ§γγ
εγ¬γ³γγΌγγΉγγγε―θ½γ§γγγ¨ React γ«δΌγγγγγ«γ― false γθΏγγΎγγ
注ζηΉ
-
γοΏ½?γ‘γ½γγγ―γγγ©γΌγγ³γΉζι©εοΏ½?γγγ γγ«εε¨γγ¦γγΎγγγγγγοΏ½?γ‘γ½γγγγͺγγ¨γ³γ³γγΌγγ³γγε£γγε ΄εγ―γγΎγγγγοΏ½?ζ£γγ¦γγ γγγ
-
shouldComponentUpdateγζζΈγγγ代γγγ«γPureComponentοΏ½?δ½Ώη¨γζ€θ¨γγ¦γγ γγγPureComponentγ― props γ¨ state γζ΅ γζ―θΌγγεΏ θ¦γͺζ΄ζ°γΎγ§γΉγγγγγ¦γγΎγε―θ½ζ§γζΈγγγΎγγ -
shouldComponentUpdateγ§ζ·±γηδΎ‘ζ§γγ§γγ―γθ‘γ£γγγJSON.stringifyγδ½Ώη¨γγγγγγγ¨γ―γε§γγγΎγγγγγγ«γγγγγ©γΌγγ³γΉγγγγγ props γ¨ state οΏ½?γγΌγΏζ§ι γ«δΎεγγγγγ«γͺγγδΊζΈ¬δΈε―θ½γ«γͺγγΎγγγγγ¦γγ’γγͺγ±γΌγ·γ§γ³γζ°η§ιγγͺγΌγΊγγγͺγΉγ―γγγγζζͺοΏ½?ε ΄εγ―γ―γ©γγ·γ₯γγε±ιΊγγγγΎγγ -
falseγθΏγγ¦γγεγ³γ³γγΌγγ³γοΏ½? state γε€ζ΄γγγε ΄εγ«εγ³γ³γγΌγγ³γοΏ½?εγ¬γ³γγΌγζζ’γγγγγγ§γ―γγγΎγγγ -
falseγθΏγγ¦γγγ³γ³γγΌγγ³γγεγ¬γ³γγΌγγγͺγγγ¨γδΏθ¨Όγγγγγγ§γ―γγγΎγγγReact γ―θΏγε€γγγ³γγ¨γγ¦δ½Ώη¨γγΎγγγδ»οΏ½?ηη±γ§γ³γ³γγΌγγ³γγεγ¬γ³γγΌγγγγ¨γηγ«γγͺγ£γ¦γγγ¨ε€ζγγε ΄εγεγ¬γ³γγΌγθ‘γγγ¨γγγγΎγγ
UNSAFE_componentWillMount()
UNSAFE_componentWillMount γοΏ½?οΏ½ηΎ©γγγ¨γReact γ― constructor οΏ½?η΄εΎγ«γγγεΌγ³εΊγγΎγγγγγ―ζ΄ε²ηγͺηη±γ§εε¨γγγοΏ½?γ§γγγζ°γγγ³γΌγγ§γ―δ½Ώη¨γγΉγγ§γ―γγγΎγγγ代γγγ«δ»₯δΈοΏ½?代ζΏζοΏ½?οΏ½οΏ½?γγγγγδ½Ώη¨γγ¦γγ γγγ
- state γεζεγγγγγ«γ―γ
stateγγ―γ©γΉγγ£γΌγ«γγ¨γγ¦οΏ½?οΏ½θ¨γγγγconstructorγ§this.stateγθ¨οΏ½?οΏ½γγΎγγ - ε―δ½η¨γοΏ½?οΏ½θ‘γγεΏ
θ¦γγγγγγ΅γγΉγ―γͺγγ·γ§γ³γθ¨οΏ½?οΏ½γγεΏ
θ¦γγγε ΄εγ―γγοΏ½?γγΈγγ―γ
componentDidMountγ«η§»εγγΎγγ
οΏ½?οΏ½ε ¨γ§γͺγγ©γ€γγ΅γ€γ―γ«γγοΏ½?η§»θ‘δΎγθ¦γ
εΌζ°
UNSAFE_componentWillMount γ―εΌζ°γεγεγγΎγγγ
θΏγε€
UNSAFE_componentWillMount γ―δ½γθΏγγ¦γ―γγγΎγγγ
注ζηΉ
-
γ³γ³γγΌγγ³γγ
static getDerivedStateFromPropsγΎγγ―getSnapshotBeforeUpdateγοΏ½?οΏ½θ£ γγ¦γγε ΄εγUNSAFE_componentWillMountγ―εΌγ³εΊγγγΎγγγ -
SuspenseοΏ½?γγγͺγ’γγ³γͺ React ζ©θ½γδ½Ώη¨γγ¦γγγ’γγͺγ§γ―γUNSAFE_componentWillMountγ―γοΏ½?εεγ«εγγ¦γγ³γ³γγΌγγ³γγζ¬ε½γ«γγ¦γ³γγγγγγ¨γδΏθ¨ΌγγΎγγγοΌδΎγγ°εγ³γ³γγΌγγ³γοΏ½?γ³γΌγγγΎγ γγΌγγγγ¦γγͺγγͺγ©οΏ½?ηη±γ§οΌγ¬γ³γγΌοΏ½?試θ‘γγ΅γΉγγ³γγγε ΄εγReact γ―ι²θ‘δΈοΏ½?γγͺγΌγη ΄ζ£γγ欑�?試θ‘γ«γ¦γ³γ³γγΌγγ³γγγΌγγγζ§η―γγγγ¨γγΎγγγγγγοΏ½?γ‘γ½γγγ βunsafeβ γ¨γͺγ£γ¦γγηη±γ§γγοΏ½?οΏ½ιγ«γγ¦γ³γγγγγ¨γγδΊοΏ½?οΏ½γ«δΎεγγγ³γΌγοΌγ΅γγΉγ―γͺγγ·γ§γ³οΏ½?θΏ½ε γͺγ©οΌγ―componentDidMountγ«ε ₯γγγΉγγ§γγ -
UNSAFE_componentWillMountγ―γ΅γΌγγ¬γ³γγͺγ³γ°δΈγ«οΏ½?οΏ½θ‘γγγε―δΈοΏ½?γ©γ€γγ΅γ€γ―γ«γ‘γ½γγγ§γγηΎοΏ½?οΏ½ηγ«γ―γγγγε©η¨οΏ½?ηγ«γγγ¦γγγ―constructorγ¨εδΈγ§γγγγγγοΏ½?γΏγ€γοΏ½?γγΈγγ―γ«γ―constructorγδ½Ώη¨γγΉγγ§γγ
UNSAFE_componentWillReceiveProps(nextProps, nextContext)
UNSAFE_componentWillReceiveProps γοΏ½?οΏ½ηΎ©γγγ¨γγ³γ³γγΌγγ³γγζ°γγ props γεγεγγ¨γγ« React γγγγεΌγ³εΊγγΎγγγγγ―ζ΄ε²ηγͺηη±γ§εε¨γγγοΏ½?γ§γγγζ°γγγ³γΌγγ§γ―δ½Ώη¨γγΉγγ§γ―γγγΎγγγ代γγγ«δ»₯δΈοΏ½?代ζΏζοΏ½?οΏ½οΏ½?γγγγγδ½Ώη¨γγ¦γγ γγγ
- props οΏ½?ε€ζ΄γ«εΏγγ¦ε―δ½η¨γοΏ½?οΏ½θ‘γγεΏ
θ¦γγγε ΄εοΌδΎγγ°γγγΌγΏοΏ½?εεΎγγ’γγ‘γΌγ·γ§γ³οΏ½?οΏ½?οΏ½θ‘γγΎγγ―γ΅γγΉγ―γͺγγ·γ§γ³οΏ½?εεζεοΌγγοΏ½?γγΈγγ―γ代γγγ«
componentDidUpdateγ«η§»εγγ¦γγ γγγ - δΈι¨οΏ½? props γε€ζ΄γγγγ¨γγ«γγγγΌγΏοΏ½?εθ¨οΏ½?οΏ½γιΏγγεΏ θ¦γγγε ΄εγ代γγγ«γ‘γ’εγγ«γγΌγδ½Ώη¨γγ¦γγ γγγ
- props γε€ζ΄γγγγ¨γγ«γγ state γγγͺγ»γγγγγεΏ θ¦γγγε ΄εγγ³γ³γγΌγγ³γγοΏ½?οΏ½ε ¨γ«εΆεΎ‘γγγγ³γ³γγΌγγ³γγ«γγγγkey δ»γοΏ½?ιεΆεΎ‘γ³γ³γγΌγγ³γγ«γγγγ¨γζ€θ¨γγ¦γγ γγγ
- props γε€ζ΄γγγγ¨γγ«γγ state γγθͺΏζ΄γγγεΏ
θ¦γγγε ΄εγγ¬γ³γγΌδΈγ« props οΏ½?γΏγγεΏ
θ¦γͺζ
ε ±γγγΉγ¦θ¨οΏ½?οΏ½γ§γγͺγγη’Ίθͺγγ¦γγ γγγγ§γγͺγε ΄εγ―γ代γγγ«
static getDerivedStateFromPropsγδ½Ώη¨γγ¦γγ γγγ
οΏ½?οΏ½ε ¨γ§γͺγγ©γ€γγ΅γ€γ―γ«γγοΏ½?η§»θ‘οΏ½?δΎγθ¦γ
εΌζ°
nextProps: γ³γ³γγΌγγ³γγθ¦ͺγ³γ³γγΌγγ³γγγεγεγγγ¨γγ¦γγ欑�? propsγδ½γε€ζ΄γγγγγε€ζγγγγγ«nextPropsγthis.propsγ¨ζ―θΌγγΎγγnextContext: γ³γ³γγΌγγ³γγζγθΏγγγγγ€γγγεγεγγγ¨γγ¦γγ欑�?γ³γ³γγ―γΉγγδ½γε€ζ΄γγγγγε€ζγγγγγ«nextContextγthis.contextγ¨ζ―θΌγγΎγγstatic contextTypeοΌηΎθ‘ηοΌγΎγγ―static contextTypesοΌγ¬γ¬γ·γΌοΌγζοΏ½?οΏ½γγε ΄εοΏ½?γΏε©η¨ε―θ½γ§γγ
θΏγε€
UNSAFE_componentWillReceiveProps γ―δ½γθΏγγ¦γ―γγγΎγγγ
注ζηΉ
-
static getDerivedStateFromPropsγΎγγ―getSnapshotBeforeUpdateγοΏ½?οΏ½θ£ γγ¦γγγ³γ³γγΌγγ³γγ§γ―γUNSAFE_componentWillReceivePropsγ―εΌγ³εΊγγγΎγγγ -
SuspenseοΏ½?γγγͺγ’γγ³γͺ React ζ©θ½γδ½Ώη¨γγ¦γγγ’γγͺγ§γ―γUNSAFE_componentWillReceivePropsγ―γοΏ½?εεγ«εγγ¦γγ³γ³γγΌγγ³γγγοΏ½? props γζ¬ε½γ«εγεγγγ¨γδΏθ¨ΌγγΎγγγοΌδΎγγ°εγ³γ³γγΌγγ³γοΏ½?γ³γΌγγγΎγ γγΌγγγγ¦γγͺγγͺγ©οΏ½?ηη±γ§οΌγ¬γ³γγΌοΏ½?試θ‘γγ΅γΉγγ³γγγε ΄εγReact γ―ι²θ‘δΈοΏ½?γγͺγΌγη ΄ζ£γγ欑�?試θ‘γ«γ¦γ³γ³γγΌγγ³γγγΌγγγζ§η―γγγγ¨γγΎγγ欑�?γ¬γ³γγΌοΏ½?試θ‘οΏ½?ζηΉγ§γ―γprops γ―η°γͺγ£γ¦γγε―θ½ζ§γγγγΎγγγγγγοΏ½?γ‘γ½γγγ βunsafeβ γ¨γͺγ£γ¦γγηη±γ§γγγ³γγγγγγζ΄ζ°οΏ½?γΏγ«ε―Ύγγ¦οΏ½?οΏ½θ‘γγΉγγ³γΌγοΌγ΅γγΉγ―γͺγγ·γ§γ³οΏ½?γͺγ»γγγͺγ©οΌγ―γcomponentDidUpdateγ«ε ₯γγγΉγγ§γγ -
UNSAFE_componentWillReceivePropsγεΌγ°γγ¦γγ³γ³γγΌγγ³γγεεγ¨η°γͺγ props γεγεγ£γγγ¨γζε³γγγοΏ½?γ§γ―γγγΎγγγδ½γγε€γγ£γγγ©γγγη’Ίθͺγγγ«γ―nextPropsγ¨this.propsγθͺεγ§ζ―θΌγγεΏ θ¦γγγγΎγγ -
React γ―γγ¦γ³γζγ«
UNSAFE_componentWillReceivePropsγεζ props γεΌζ°γ«εΌγ³εΊγγγ¨γ―γγγΎγγγγοΏ½?γ‘γ½γγγ―γγ³γ³γγΌγγ³γοΏ½? props οΏ½?δΈι¨γζ΄ζ°γγγδΊοΏ½?οΏ½οΏ½?ε ΄εγ«οΏ½?γΏεΌγ³εΊγγγΎγγδΎγγ°γsetStateγεΌγ³εΊγγ¦γγδΈθ¬ηγ«γ―εγγ³γ³γγΌγγ³γε οΏ½?UNSAFE_componentWillReceivePropsγ―γγͺγ¬γγγΎγγγ
UNSAFE_componentWillUpdate(nextProps, nextState)
UNSAFE_componentWillUpdate γοΏ½?οΏ½ηΎ©γγγ¨γζ°γγ props γΎγγ― state γ§γ¬γ³γγΌγγεγ« React γγγγεΌγ³εΊγγΎγγγγγ―ζ΄ε²ηγͺηη±γ§εε¨γγγοΏ½?γ§γγγζ°γγγ³γΌγγ§γ―δ½Ώη¨γγΉγγ§γ―γγγΎγγγ代γγγ«δ»₯δΈοΏ½?代ζΏζοΏ½?οΏ½οΏ½?γγγγγδ½Ώη¨γγ¦γγ γγγ
- prop γΎγγ― state οΏ½?ε€ζ΄γ«εΏγγ¦ε―δ½η¨οΌδΎγγ°γγγΌγΏοΏ½?εεΎγγ’γγ‘γΌγ·γ§γ³οΏ½?οΏ½?οΏ½θ‘γγ΅γγΉγ―γͺγγ·γ§γ³οΏ½?εεζεγͺγ©οΌγοΏ½?οΏ½θ‘γγεΏ
θ¦γγγε ΄εγγοΏ½?γγΈγγ―γ
componentDidUpdateγ«η§»εγγ¦γγ γγγ - DOM γγζ
ε ±γθͺγΏεγοΌδΎγγ°γηΎε¨οΏ½?γΉγ―γγΌγ«δ½οΏ½?γδΏεγγγͺγ©οΌγγγγεΎγ§
componentDidUpdateγ§δ½Ώη¨γγε ΄εγ―γgetSnapshotBeforeUpdateε γ§θͺγΏεγγγγ«γγ¦γγ γγγ
οΏ½?οΏ½ε ¨γ§γͺγγ©γ€γγ΅γ€γ―γ«γγοΏ½?η§»θ‘δΎγθ¦γ
εΌζ°
nextProps: γ³γ³γγΌγγ³γγ欑γ«γ¬γ³γγΌγγδΊοΏ½?οΏ½οΏ½? propsγδ½γε€γγ£γγγε€ζγγγγγ«γnextPropsγ¨this.propsγζ―θΌγγΎγγnextState: γ³γ³γγΌγγ³γγ欑γ«γ¬γ³γγΌγγδΊοΏ½?οΏ½οΏ½? stateγδ½γε€γγ£γγγε€ζγγγγγ«γnextStateγ¨this.stateγζ―θΌγγΎγγ
θΏγε€
UNSAFE_componentWillUpdate γ―δ½γθΏγγ¦γ―γγγΎγγγ
注ζηΉ
-
shouldComponentUpdateγοΏ½?οΏ½ηΎ©γγγ¦γγfalseγθΏγε ΄εγUNSAFE_componentWillUpdateγ―εΌγ³εΊγγγΎγγγ -
γ³γ³γγΌγγ³γγ
static getDerivedStateFromPropsγΎγγ―getSnapshotBeforeUpdateγοΏ½?οΏ½θ£ γγ¦γγε ΄εγUNSAFE_componentWillUpdateγ―εΌγ³εΊγγγΎγγγ -
componentWillUpdateοΏ½?εΌγ³εΊγδΈγ«setStateοΌγΎγγ―ζη΅ηγ«setStateγεΌγ³εΊγγγγγγͺγγγγγ‘γ½γγγδΎγγ° Redux γ’γ―γ·γ§γ³οΏ½?γγ£γΉγγγοΌγεΌγ³εΊγγγ¨γ―γ΅γγΌγγγγ¦γγΎγγγ -
SuspenseοΏ½?γγγͺγ’γγ³γͺ React ζ©θ½γδ½Ώη¨γγ¦γγγ’γγͺγ§γ―γUNSAFE_componentWillUpdateγ―γοΏ½?εεγ«εγγ¦γγ³γ³γγΌγγ³γγζ¬ε½γ«ζ΄ζ°γγγγγ¨γδΏθ¨ΌγγΎγγγοΌδΎγγ°εγ³γ³γγΌγγ³γοΏ½?γ³γΌγγγΎγ γγΌγγγγ¦γγͺγγͺγ©οΏ½?ηη±γ§οΌγ¬γ³γγΌοΏ½?試θ‘γγ΅γΉγγ³γγγε ΄εγReact γ―ι²θ‘δΈοΏ½?γγͺγΌγη ΄ζ£γγ欑�?試θ‘γ«γ¦γ³γ³γγΌγγ³γγγΌγγγζ§η―γγγγ¨γγΎγγ欑�?γ¬γ³γγΌοΏ½?試θ‘οΏ½?ζηΉγ§γ― props γ¨ state γ―η°γͺγ£γ¦γγε―θ½ζ§γγγγΎγγγγγγοΏ½?γ‘γ½γγγ βunsafeβ γ¨γͺγ£γ¦γγηη±γ§γγγ³γγγγγγζ΄ζ°οΏ½?γΏγ«ε―Ύγγ¦οΏ½?οΏ½θ‘γγΉγγ³γΌγοΌγ΅γγΉγ―γͺγγ·γ§γ³οΏ½?γͺγ»γγγͺγ©οΌγ―γcomponentDidUpdateγ«ε ₯γγγΉγγ§γγ -
UNSAFE_componentWillUpdateγεΌγ°γγ¦γγ³γ³γγΌγγ³γγεεγ¨γ―η°γͺγ props γ state γεγεγ£γγγ¨γζε³γγγοΏ½?γ§γ―γγγΎγγγδ½γγε€γγ£γγγ©γγγη’Ίθͺγγγ«γ―γnextPropsγ¨this.propsγnextStateγ¨this.stateγθͺεγ§ζ―θΌγγεΏ θ¦γγγγΎγγ -
React γ― props γ state οΏ½?εζε€γδ½Ώγ£γ¦γγ¦γ³γζγ«
UNSAFE_componentWillUpdateγεΌγ³εΊγγγ¨γ―γγΎγγγ
static childContextTypes
γοΏ½?γ³γ³γγΌγγ³γγ«γγ£γ¦ζδΎγγγγ¬γ¬γ·γΌγ³γ³γγ―γΉγγζοΏ½?οΏ½γγΎγγ
static contextTypes
γοΏ½?γ³γ³γγΌγγ³γγδ½Ώη¨γγγ¬γ¬γ·γΌγ³γ³γγ―γΉγγζοΏ½?οΏ½γγΎγγ
static contextType
γ―γ©γΉγ³γ³γγΌγγ³γγ§ this.context γθͺγΏεγγγε ΄εγθͺγΏεγγγγ³γ³γγ―γΉγγγγγ§ζοΏ½?οΏ½γγεΏ
θ¦γγγγΎγγstatic contextType γ¨γγ¦ζοΏ½?οΏ½γγγ³γ³γγ―γΉγγ―γδ»₯εγ« createContext γ§δ½ζγγγ¦γγε€γ§γͺγγγ°γͺγγΎγγγ
class Button extends Component {
static contextType = ThemeContext;
render() {
const theme = this.context;
const className = 'button-' + theme;
return (
<button className={className}>
{this.props.children}
</button>
);
}
}static defaultProps
γ―γ©γΉοΏ½?γγγ©γ«γοΏ½? props γθ¨οΏ½?οΏ½γγγγγ« static defaultProps γοΏ½?οΏ½ηΎ©γ§γγΎγγγγγγ― undefined γγγ³εε¨γγͺγ props γ«ε―Ύγγ¦δ½Ώη¨γγγΎγγγnull γ§γγ props γ«γ―δ½Ώη¨γγγΎγγγ
δΎγγ°δ»₯δΈοΏ½?γγγ«γγ¦γprops γ§γγ color γγγγ©γ«γγ§ 'blue' γ«γͺγγγοΏ½?οΏ½ηΎ©γ§γγΎγγ
class Button extends Component {
static defaultProps = {
color: 'blue'
};
render() {
return <button className={this.props.color}>click me</button>;
}
}color prop γζΈ‘γγγͺγε ΄εγ undefined γ§γγε ΄εγγγγ©γ«γγ§ 'blue' γ«γ»γγγγγΎγγ
<>
{/* this.props.color is "blue" */}
<Button />
{/* this.props.color is "blue" */}
<Button color={undefined} />
{/* this.props.color is null */}
<Button color={null} />
{/* this.props.color is "red" */}
<Button color="red" />
</>static propTypes
γ³γ³γγΌγγ³γγεγε
₯γγ props οΏ½?εγοΏ½?οΏ½θ¨γγγγγ«γprop-types γ©γ€γγ©γͺγ¨δΈη·γ« static propTypes γοΏ½?οΏ½ηΎ©γγγγ¨γγ§γγΎγγγγγοΏ½?εγ―γ¬γ³γγΌδΈγγγ€ιηΊδΈγ«οΏ½?γΏγγ§γγ―γγγΎγγ
import PropTypes from 'prop-types';
class Greeting extends React.Component {
static propTypes = {
name: PropTypes.string
};
render() {
return (
<h1>Hello, {this.props.name}</h1>
);
}
}static getDerivedStateFromError(error)
static getDerivedStateFromError γοΏ½?οΏ½ηΎ©γγγ¨γεγ³γ³γγΌγγ³γοΌι γοΏ½?εγε«γοΌγγ¬γ³γγΌδΈγ«γ¨γ©γΌγγΉγγΌγγγ¨γγ« React γγγγεΌγ³εΊγγΎγγγγγ«γγγUI γγ―γͺγ’γγ代γγγ«γ¨γ©γΌγ‘γγ»γΌγΈγ葨瀺γ§γγΎγγ
ιεΈΈγγγ―γγ¨γ©γΌγ¬γγΌγγδ½γγοΏ½?εζγ΅γΌγγΉγ«ιδΏ‘γ§γγγγγ«γγγγοΏ½? componentDidCatch γ¨δΈη·γ«δ½Ώη¨γγγΎγγγγγοΏ½?γ‘γ½γγγζγ€γ³γ³γγΌγγ³γοΏ½?γγ¨γγ¨γ©γΌγγ¦γ³γγͺγ¨εΌγ³γΎγγ
εΌζ°
error: γΉγγΌγγγγ¨γ©γΌγηΎοΏ½?οΏ½ηγ«γ―ιεΈΈErrorοΏ½?γ€γ³γΉγΏγ³γΉγ«γͺγγΎγγγγοΏ½?γγ¨γ―δΏθ¨Όγγγ¦γγΎγγγJavaScript γ§γ―ζεεγnullγγε«γγδ»»ζοΏ½?ε€γthrowγγγγ¨γ許γγγ¦γγγγγ§γγ
θΏγε€
static getDerivedStateFromError γγγ―γγ¨γ©γΌγ‘γγ»γΌγΈγ葨瀺γγγγγ³γ³γγΌγγ³γγ«ζη€ΊγγγγοΏ½? state γθΏγγΎγγ
注ζηΉ
static getDerivedStateFromErrorγ―η΄ι’ζ°γ§γγγΉγγ§γγε―δ½η¨οΌδΎγγ°γεζγ΅γΌγγΉοΏ½?εΌγ³εΊγοΌγοΏ½?οΏ½θ‘γγγε ΄εγ―γcomponentDidCatchγοΏ½?οΏ½θ£ γγεΏ θ¦γγγγΎγγ
static getDerivedStateFromProps(props, state)
static getDerivedStateFromProps γοΏ½?οΏ½ηΎ©γγγ¨γReact γ―εεοΏ½?γγ¦γ³γγ¨γοΏ½?εΎοΏ½?ζ΄ζ°οΏ½?δΈ‘ζΉγ§γrender γεΌγ³εΊγη΄εγ«γγγεΌγ³εΊγγΎγγstate γζ΄ζ°γγγγοΏ½?γͺγγΈγ§γ―γγθΏγγγδ½γζ΄ζ°γγͺγε ΄εγ― null γθΏγγγγ«γγΎγγ
γοΏ½?γ‘γ½γγγ―γstate γ props οΏ½?η΅ζηγͺε€εγ«δΎεγγγ¨γγη¨γͺγ¦γΌγΉγ±γΌγΉοΏ½?γγγ«εε¨γγΎγγδΎγγ°γγοΏ½? Form γ³γ³γγΌγγ³γγ― props γ§γγ userID γε€ζ΄γγγγ¨γγ« state γ§γγ email γγͺγ»γγγγΎγγ
class Form extends Component {
state = {
email: this.props.defaultEmail,
prevUserID: this.props.userID
};
static getDerivedStateFromProps(props, state) {
// Any time the current user changes,
// Reset any parts of state that are tied to that user.
// In this simple example, that's just the email.
if (props.userID !== state.prevUserID) {
return {
prevUserID: props.userID,
email: props.defaultEmail
};
}
return null;
}
// ...
}γοΏ½?γγΏγΌγ³γ§γ―γοΌuserID οΏ½?γγγͺοΌprops οΏ½?εεοΏ½?ε€γγοΌprevUserID οΏ½?γγγͺοΌstate γ«δΏζγγεΏ
θ¦γγγγγ¨γ«ζ³¨ζγγ¦γγ γγγ
εΌζ°
props: γ³γ³γγΌγγ³γγγ¬γ³γγΌγγγγ¨γγ¦γγ欑�? propsγstate: γ³γ³γγΌγγ³γγγ¬γ³γγΌγγγγ¨γγ¦γγ欑�? stateγ
θΏγε€
static getDerivedStateFromProps γ―γstate γζ΄ζ°γγγγοΏ½?γͺγγΈγ§γ―γγθΏγγγδ½γζ΄ζ°γγͺγε ΄εγ― null γθΏγγΎγγ
注ζηΉ
-
γοΏ½?γ‘γ½γγγ―γεε γ«ι’δΏγͺγγγΉγ¦οΏ½?γ¬γ³γγΌγ§ηΊη«γγΎγγ
UNSAFE_componentWillReceivePropsγ―γγγ¨γ―η°γͺγγθ¦ͺγεγ¬γ³γγΌγεΌγθ΅·γγγγ¨γοΏ½?γΏηΊη«γγγγΌγ«γ«οΏ½?setStateοΏ½?η΅ζγ¨γγ¦γ―ηΊη«γγΎγγγ -
γοΏ½?γ‘γ½γγγ―γ³γ³γγΌγγ³γοΏ½?γ€γ³γΉγΏγ³γΉγ«γ’γ―γ»γΉγ§γγΎγγγγζγΏγ§γγγ°γγ³γ³γγΌγγ³γοΏ½? props γ¨ state γ«ε―Ύγγη΄ι’ζ°γγ―γ©γΉοΏ½?οΏ½ηΎ©οΏ½?ε€ι¨γ«ζ½εΊγγγγ¨γ§γ
static getDerivedStateFromPropsγ¨δ»οΏ½?γ―γ©γΉγ‘γ½γγγ¨οΏ½?ιγ§γ³γΌγγεε©η¨γγγγ¨γγ§γγΎγγ
δ½Ώη¨ζ³
γ―γ©γΉγ³γ³γγΌγγ³γγοΏ½?οΏ½ηΎ©γγ
React οΏ½?γ³γ³γγΌγγ³γγγ―γ©γΉγ¨γγ¦οΏ½?οΏ½ηΎ©γγγ«γ―γη΅γΏθΎΌγΏοΏ½? Component γ―γ©γΉγηΆζΏγγrender γ‘γ½γγγοΏ½?οΏ½ηΎ©γγΎγγ
import { Component } from 'react';
class Greeting extends Component {
render() {
return <h1>Hello, {this.props.name}!</h1>;
}
}React γ―γη»ι’γ«δ½γ葨瀺γγγγη₯γγγγ«γrender γ‘γ½γγγεΌγ³εΊγγΎγγιεΈΈγγγγγγ― JSX γθΏγγΎγγrender γ‘γ½γγγ―η΄ι’ζ°γ§γγγγ€γΎγ JSX οΏ½?θ¨οΏ½?οΏ½οΏ½?γΏγθ‘γεΏ
θ¦γγγγΎγγ
ι’ζ°γ³γ³γγΌγγ³γγ¨εζ§γ«γγ―γ©γΉγ³γ³γγΌγγ³γγ§γθ¦ͺγ³γ³γγΌγγ³γγγ props γιγγ¦ζ
ε ±γεγεγγγ¨γγ§γγΎγγγγ γγprops γθͺγΏεγγγοΏ½?ζ§ζγ―η°γͺγγΎγγδΎγγ°γθ¦ͺγ³γ³γγΌγγ³γγ <Greeting name="Taylor" /> γγ¬γ³γγΌγγε ΄εγγοΏ½? name γγγγγ£γ― this.props γγ this.props.name οΏ½?γγγ«γγ¦θͺγΏεγγΎγγ
import { Component } from 'react'; class Greeting extends Component { render() { return <h1>Hello, {this.props.name}!</h1>; } } export default function App() { return ( <> <Greeting name="Sara" /> <Greeting name="Cahal" /> <Greeting name="Edite" /> </> ); }
γγγ―οΌuse γ§ε§γΎγ useState οΏ½?γγγͺι’ζ°οΌγ―γ―γ©γΉγ³γ³γγΌγγ³γε
γ§γ―γ΅γγΌγγγγ¦γγͺγγγ¨γ«ζ³¨ζγγ¦γγ γγγ
γ―γ©γΉγ³γ³γγΌγγ³γγ« state γθΏ½ε γγ
γ―γ©γΉγ« state γθΏ½ε γγγ«γ―γstate γ¨γγγγγγγ£γ«γͺγγΈγ§γ―γγε²γε½γ¦γΎγγstate γζ΄ζ°γγγ«γ―γthis.setState γεΌγ³εΊγγΎγγ
import { Component } from 'react'; export default class Counter extends Component { state = { name: 'Taylor', age: 42, }; handleNameChange = (e) => { this.setState({ name: e.target.value }); } handleAgeChange = () => { this.setState({ age: this.state.age + 1 }); }; render() { return ( <> <input value={this.state.name} onChange={this.handleNameChange} /> <button onClick={this.handleAgeChange}> Increment age </button> <p>Hello, {this.state.name}. You are {this.state.age}.</p> </> ); } }
γ―γ©γΉγ³γ³γγΌγγ³γγ«γ©γ€γγ΅γ€γ―γ«γ‘γ½γγγθΏ½ε γγ
γ―γ©γΉγ«γ―γγγ€γοΏ½?ηΉε₯γͺγ‘γ½γγγοΏ½?οΏ½ηΎ©γγγγ¨γγ§γγΎγγ
componentDidMount γ‘γ½γγγοΏ½?οΏ½ηΎ©γγγ¨γγ³γ³γγΌγγ³γγη»ι’γ«θΏ½ε γγγοΌγγ¦γ³γγγγοΌγ¨γγ« React γγγγεΌγ³εΊγγΎγγprops γ state οΏ½?ε€ζ΄γ«γγγ³γ³γγΌγγ³γγεγ¬γ³γγΌγγγεΎγ«γReact γ― componentDidUpdate γεΌγ³εΊγγΎγγγ³γ³γγΌγγ³γγη»ι’γγει€γγγοΌγ’γ³γγ¦γ³γγγγοΌιγ«γReact γ― componentWillUnmount γεΌγ³εΊγγΎγγ
componentDidMount γοΏ½?οΏ½θ£
γγε ΄εγιεΈΈγ―γγ°γιΏγγγγγ« 3 γ€γγΉγ¦οΏ½?γ©γ€γγ΅γ€γ―γ«γοΏ½?οΏ½θ£
γγεΏ
θ¦γγγγΎγγδΎγγ°γcomponentDidMount γδ½γγοΏ½? state γ props γθͺγΏεγε ΄εγ―γγγγ«ε€ζ΄γγγ£γε ΄εγ«ε¦ηγγγγγ« componentDidUpdate γοΏ½?οΏ½θ£
γγεΏ
θ¦γγγγcomponentDidMount γοΏ½?οΏ½θ‘γγγγ¨γγ―γͺγΌγ³γ’γγγγγγγ«γ― componentWillUnmount γοΏ½?οΏ½θ£
γγεΏ
θ¦γγγγΎγγ
δΎγγ°γδ»₯δΈοΏ½? ChatRoom γ³γ³γγΌγγ³γγ―γγγ£γγγΈοΏ½?ζ₯ηΆγ props γγγ³ state γ¨εζγγγ¦γγΎγγ
import { Component } from 'react'; import { createConnection } from './chat.js'; export default class ChatRoom extends Component { state = { serverUrl: 'https://localhost:1234' }; componentDidMount() { this.setupConnection(); } componentDidUpdate(prevProps, prevState) { if ( this.props.roomId !== prevProps.roomId || this.state.serverUrl !== prevState.serverUrl ) { this.destroyConnection(); this.setupConnection(); } } componentWillUnmount() { this.destroyConnection(); } setupConnection() { this.connection = createConnection( this.state.serverUrl, this.props.roomId ); this.connection.connect(); } destroyConnection() { this.connection.disconnect(); this.connection = null; } render() { return ( <> <label> Server URL:{' '} <input value={this.state.serverUrl} onChange={e => { this.setState({ serverUrl: e.target.value }); }} /> </label> <h1>Welcome to the {this.props.roomId} room!</h1> </> ); } }
ιηΊζγ« Strict Mode γζεΉοΏ½?ε ΄εγReact γ― componentDidMount γεΌγ³εΊγγη΄εΎγ« componentWillUnmount γεΌγ³εΊγγγοΏ½?εΎεγ³ componentDidMount γεΌγ³εΊγγΎγγγγγ«γγγcomponentWillUnmount οΏ½?οΏ½?οΏ½θ£
γεΏγγε ΄εγγγοΏ½?γγΈγγ―γ componentDidMount οΏ½?ζεγ¨ζ£γγγι‘οΏ½?γγγ«ε―ΎεΏγγγ¦γγͺγε ΄εγ«ζ°γ₯γγγγγͺγγΎγγ
γ¨γ©γΌγγ¦γ³γγͺγ§γ¬γ³γγΌδΈοΏ½?γ¨γ©γΌγγγ£γγγγ
γγγ©γ«γγ§γ―γγ’γγͺγ±γΌγ·γ§γ³γγ¬γ³γγΌδΈγ«γ¨γ©γΌγγΉγγΌγγγ¨γReact γ―γοΏ½? UI γη»ι’γγει€γγΎγγγγγι²γγγγ«γUI γγ¨γ©γΌγγ¦γ³γγͺγ«γ©γγγγγγ¨γγ§γγΎγγγ¨γ©γΌγγ¦γ³γγͺγ―γγ―γ©γγ·γ₯γγι¨δ½οΏ½?代γγγ«γδΎγγ°γ¨γ©γΌγ‘γγ»γΌγΈγͺγ©οΏ½?γγ©γΌγ«γγγ― UI γ葨瀺γγγγοΏ½?γηΉε₯γͺγ³γ³γγΌγγ³γγ§γγ
γ¨γ©γΌγγ¦γ³γγͺγ³γ³γγΌγγ³γγοΏ½?οΏ½θ£
γγγγγ«γ―γγ¨γ©γΌγ«εεΏγγ¦ state γζ΄ζ°γγγ¦γΌγΆγ«γ¨γ©γΌγ‘γγ»γΌγΈγ葨瀺γγγγοΏ½? static getDerivedStateFromError γζδΎγγεΏ
θ¦γγγγΎγγγΎγγͺγγ·γ§γ³γ§γδΎγγ°γ¨γ©γΌγεζγ΅γΌγγΉγ«θ¨ι²γγγͺγ©οΏ½?θΏ½ε οΏ½?γγΈγγ―γθΏ½ε γγγγγ« componentDidCatch γοΏ½?οΏ½θ£
γγγγ¨γγ§γγΎγγ
class ErrorBoundary extends React.Component {
constructor(props) {
super(props);
this.state = { hasError: false };
}
static getDerivedStateFromError(error) {
// Update state so the next render will show the fallback UI.
return { hasError: true };
}
componentDidCatch(error, info) {
// Example "componentStack":
// in ComponentThatThrows (created by App)
// in ErrorBoundary (created by App)
// in div (created by App)
// in App
logErrorToMyService(error, info.componentStack);
}
render() {
if (this.state.hasError) {
// You can render any custom fallback UI
return this.props.fallback;
}
return this.props.children;
}
}欑γ«γγ³γ³γγΌγγ³γγγͺγΌοΏ½?δΈι¨γγγγ§γ©γγγγΎγγ
<ErrorBoundary fallback={<p>Something went wrong</p>}>
<Profile />
</ErrorBoundary>γγ Profile γγγγ―γοΏ½?εγ³γ³γγΌγγ³γγγ¨γ©γΌγγΉγγΌγγγ¨γErrorBoundary γ―γοΏ½?γ¨γ©γΌγγγγ£γγγγγζοΏ½?οΏ½γγγ¨γ©γΌγ‘γγ»γΌγΈγ¨γ¨γγ«γγ©γΌγ«γγγ― UI γ葨瀺γγγ¨γ©γΌγ¬γγΌγγγγͺγοΏ½?γ¨γ©γΌγ¬γγΌγγ£γ³γ°γ΅γΌγγΉγ«ιδΏ‘γγΎγγ
γγΉγ¦οΏ½?γ³γ³γγΌγγ³γγε₯γ οΏ½?γ¨γ©γΌγγ¦γ³γγͺγ§γ©γγγγεΏ θ¦γ―γγγΎγγγγ¨γ©γΌγγ¦γ³γγͺοΏ½?η²εΊ¦γ«γ€γγ¦θγγιγ―γγ¨γ©γΌγ‘γγ»γΌγΈγγ©γγ«θ‘¨η€ΊγγοΏ½?γηγ«γγͺγ£γ¦γγγγθγγ¦γΏγ¦γγ γγγδΎγγ°γγ‘γγ»γΌγΈγ³γ°γ’γγͺγ§γ―γδΌθ©±οΏ½?γͺγΉγγγ¨γ©γΌγγ¦γ³γγͺγ§ε²γοΏ½?γηγ«γγͺγ£γ¦γγΎγγγΎγγγ‘γγ»γΌγΈγεε₯γ«ε²γγγ¨γηγ«γγͺγ£γ¦γγγ§γγγγγγγγγ’γγΏγΌγ 1 γ€γγ€ε²γγγ¨γ«γ―ζε³γγγγΎγγγ
代ζΏζ‘
γ·γ³γγ«γͺγ³γ³γγΌγγ³γγγ―γ©γΉγγι’ζ°γΈη§»θ‘
δΈθ¬ηγ«γ―γ³γ³γγΌγγ³γγ―ι’ζ°γ¨γγ¦οΏ½?οΏ½ηΎ©γγΎγγ
δΎγγ°γγοΏ½? Greeting γ―γ©γΉγ³γ³γγΌγγ³γγι’ζ°γ«ζΈγζγγγγ¨γγΎγγ
import { Component } from 'react'; class Greeting extends Component { render() { return <h1>Hello, {this.props.name}!</h1>; } } export default function App() { return ( <> <Greeting name="Sara" /> <Greeting name="Cahal" /> <Greeting name="Edite" /> </> ); }
Greeting γ¨γγι’ζ°γοΏ½?οΏ½ηΎ©γγ¦γγ γγγγγγ« render ι’ζ°οΏ½?ζ¬δ½γη§»εγγΎγγ
function Greeting() {
// ... move the code from the render method here ...
}this.props.name γ¨γγ代γγγ«γprops γ§γγ name γ―εε²δ»£ε
₯ζ§ζγδ½Ώη¨γγ¦οΏ½?οΏ½ηΎ©γγη΄ζ₯θͺγΏεγγΎγοΌ
function Greeting({ name }) {
return <h1>Hello, {name}!</h1>;
}οΏ½?οΏ½ε ¨γͺδΎγ―δ»₯δΈοΏ½?ιγγ§γγ
function Greeting({ name }) { return <h1>Hello, {name}!</h1>; } export default function App() { return ( <> <Greeting name="Sara" /> <Greeting name="Cahal" /> <Greeting name="Edite" /> </> ); }
state γζγ€γ³γ³γγΌγγ³γγγ―γ©γΉγγι’ζ°γΈη§»θ‘
γοΏ½? Counter γ―γ©γΉγ³γ³γγΌγγ³γγι’ζ°γ«ζΈγζγγγγ¨γγΎγγ
import { Component } from 'react'; export default class Counter extends Component { state = { name: 'Taylor', age: 42, }; handleNameChange = (e) => { this.setState({ name: e.target.value }); } handleAgeChange = (e) => { this.setState({ age: this.state.age + 1 }); }; render() { return ( <> <input value={this.state.name} onChange={this.handleNameChange} /> <button onClick={this.handleAgeChange}> Increment age </button> <p>Hello, {this.state.name}. You are {this.state.age}.</p> </> ); } }
γΎγγεΏ θ¦γ¨γͺγ state ε€ζ° γζγ£γι’ζ°γοΏ½?οΏ½θ¨γγΎγγ
import { useState } from 'react';
function Counter() {
const [name, setName] = useState('Taylor');
const [age, setAge] = useState(42);
// ...欑γ«γγ€γγ³γγγ³γγ©γζΈγζγγΎγγ
function Counter() {
const [name, setName] = useState('Taylor');
const [age, setAge] = useState(42);
function handleNameChange(e) {
setName(e.target.value);
}
function handleAgeChange() {
setAge(age + 1);
}
// ...ζεΎγ«γthis γ§ε§γΎγε€γΈοΏ½?εη
§γγγΉγ¦γγ³γ³γγΌγγ³γγ§οΏ½?οΏ½ηΎ©γγε€ζ°γ¨ι’ζ°γ«οΏ½?γζγγΎγγδΎγγ°γthis.state.age γ age γ«γthis.handleNameChange γ handleNameChange γ«οΏ½?γζγγΎγγ
οΏ½?οΏ½ε ¨γ«ζΈγζγγγγγ³γ³γγΌγγ³γγ―γγ‘γγ§γγ
import { useState } from 'react'; export default function Counter() { const [name, setName] = useState('Taylor'); const [age, setAge] = useState(42); function handleNameChange(e) { setName(e.target.value); } function handleAgeChange() { setAge(age + 1); } return ( <> <input value={name} onChange={handleNameChange} /> <button onClick={handleAgeChange}> Increment age </button> <p>Hello, {name}. You are {age}.</p> </> ) }
γ©γ€γγ΅γ€γ―γ«γ‘γ½γγγζγ€γ³γ³γγΌγγ³γγγ―γ©γΉγγι’ζ°γΈη§»θ‘
γ©γ€γγ΅γ€γ―γ«γ‘γ½γγγζγ€δ»₯δΈοΏ½? ChatRoom γ―γ©γΉγ³γ³γγΌγγ³γγι’ζ°γ«ζΈγζγγγγ¨γγΎγγ
import { Component } from 'react'; import { createConnection } from './chat.js'; export default class ChatRoom extends Component { state = { serverUrl: 'https://localhost:1234' }; componentDidMount() { this.setupConnection(); } componentDidUpdate(prevProps, prevState) { if ( this.props.roomId !== prevProps.roomId || this.state.serverUrl !== prevState.serverUrl ) { this.destroyConnection(); this.setupConnection(); } } componentWillUnmount() { this.destroyConnection(); } setupConnection() { this.connection = createConnection( this.state.serverUrl, this.props.roomId ); this.connection.connect(); } destroyConnection() { this.connection.disconnect(); this.connection = null; } render() { return ( <> <label> Server URL:{' '} <input value={this.state.serverUrl} onChange={e => { this.setState({ serverUrl: e.target.value }); }} /> </label> <h1>Welcome to the {this.props.roomId} room!</h1> </> ); } }
γΎγγ― componentWillUnmount γ componentDidMount οΏ½?ιοΏ½?εδ½γγγ¦γγγγ¨γη’Ίθͺγγ¦γγ γγγδΈθ¨οΏ½?δΎγ§γ― componentDidMount γ«γγ£γ¦η’Ίη«γγγζ₯ηΆγεζγγ¦γγοΏ½?γ§γγγγͺγ£γ¦γγΎγγγοΏ½?γγγͺγγΈγγ―γεε¨γγͺγε ΄εγγΎγγγγθΏ½ε γγ¦γγ γγγ
欑γ«γcomponentDidUpdate γ‘γ½γγγγcomponentDidMount γ§δ½Ώη¨γγ¦γγ props γ¨ state οΏ½?ε€ζ΄γε¦ηγγ¦γγγγ¨γη’Ίθͺγγ¦γγ γγγδΈθ¨οΏ½?δΎγ§γ―γcomponentDidMount γ― setupConnection γεΌγ³εΊγγ¦γγγγγγ this.state.serverUrl γ¨ this.props.roomId γθͺγΏεγ£γ¦γγΎγγγγγγ£γ¦ componentDidUpdate γ this.state.serverUrl γ¨ this.props.roomId γε€ζ΄γγγγγ©γγγη’Ίθͺγγε€ζ΄γγγ£γε ΄εγ―ζ₯ηΆγεη’Ίη«γγͺγγγ°γͺγγΎγγγcomponentDidUpdate οΏ½?γγΈγγ―γεε¨γγͺγγγγγγ―ι’ι£γγγγΉγ¦οΏ½? props γ¨ state οΏ½?ε€ζ΄γε¦ηγ§γγ¦γγͺγε ΄εγ―γγΎγγγγοΏ½?ζ£γγ¦γγ γγγ
δΈθ¨οΏ½?δΎγ§γ―γγ©γ€γγ΅γ€γ―γ«γ‘γ½γγε οΏ½?γγΈγγ―γ―γReact οΏ½?ε€ι¨οΏ½?γ·γΉγγ οΌγγ£γγγ΅γΌγοΌγ«γ³γ³γγΌγγ³γγζ₯ηΆγγ¦γγΎγγγ³γ³γγΌγγ³γγε€ι¨γ·γΉγγ γ«ζ₯ηΆγγγγγ«γ―γγοΏ½?γγΈγγ―γεδΈοΏ½?γ¨γγ§γ―γγ¨γγ¦θ¨θΏ°γγΎγγ
import { useState, useEffect } from 'react';
function ChatRoom({ roomId }) {
const [serverUrl, setServerUrl] = useState('https://localhost:1234');
useEffect(() => {
const connection = createConnection(serverUrl, roomId);
connection.connect();
return () => {
connection.disconnect();
};
}, [serverUrl, roomId]);
// ...
}γοΏ½? useEffect οΏ½?εΌγ³εΊγγ―γδΈθ¨οΏ½?γ©γ€γγ΅γ€γ―γ«γ‘γ½γγε
οΏ½?γγΈγγ―γ¨εηγ§γγγ©γ€γγ΅γ€γ―γ«γ‘γ½γγγθ€ζ°οΏ½?δΊγγ«ι’ι£γγͺγγγ¨γθ‘γ£γ¦γγε ΄εγ―γγγγγθ€ζ°οΏ½?η¬η«γγγ¨γγ§γ―γγ«εε²γγ¦γγ γγγδ»₯δΈγ«οΏ½?οΏ½ε
¨γͺδΎγη€ΊγγΎγγ
import { useState, useEffect } from 'react'; import { createConnection } from './chat.js'; export default function ChatRoom({ roomId }) { const [serverUrl, setServerUrl] = useState('https://localhost:1234'); useEffect(() => { const connection = createConnection(serverUrl, roomId); connection.connect(); return () => { connection.disconnect(); }; }, [roomId, serverUrl]); return ( <> <label> Server URL:{' '} <input value={serverUrl} onChange={e => setServerUrl(e.target.value)} /> </label> <h1>Welcome to the {roomId} room!</h1> </> ); }
γ³γ³γγ―γΉγγζγ€γ³γ³γγΌγγ³γγγ―γ©γΉγγι’ζ°γΈη§»θ‘
δ»₯δΈοΏ½?δΎγ§γ―γγ―γ©γΉγ³γ³γγΌγγ³γγ§γγ Panel γ¨ Button γγthis.context γγγ³γ³γγ―γΉγγθͺγΏεγ£γ¦γγΎγγ
import { createContext, Component } from 'react'; const ThemeContext = createContext(null); class Panel extends Component { static contextType = ThemeContext; render() { const theme = this.context; const className = 'panel-' + theme; return ( <section className={className}> <h1>{this.props.title}</h1> {this.props.children} </section> ); } } class Button extends Component { static contextType = ThemeContext; render() { const theme = this.context; const className = 'button-' + theme; return ( <button className={className}> {this.props.children} </button> ); } } function Form() { return ( <Panel title="Welcome"> <Button>Sign up</Button> <Button>Log in</Button> </Panel> ); } export default function MyApp() { return ( <ThemeContext.Provider value="dark"> <Form /> </ThemeContext.Provider> ) }
γγγγι’ζ°γ³γ³γγΌγγ³γγ«ε€ζγγε ΄εγthis.context γ useContext οΏ½?εΌγ³εΊγγ«οΏ½?γζγγΎγγ
import { createContext, useContext } from 'react'; const ThemeContext = createContext(null); function Panel({ title, children }) { const theme = useContext(ThemeContext); const className = 'panel-' + theme; return ( <section className={className}> <h1>{title}</h1> {children} </section> ) } function Button({ children }) { const theme = useContext(ThemeContext); const className = 'button-' + theme; return ( <button className={className}> {children} </button> ); } function Form() { return ( <Panel title="Welcome"> <Button>Sign up</Button> <Button>Log in</Button> </Panel> ); } export default function MyApp() { return ( <ThemeContext.Provider value="dark"> <Form /> </ThemeContext.Provider> ) }