Äú¿ÉÒÔ¾èÖú£¬Ö§³ÖÎÒÃǵĹ«ÒæÊÂÒµ¡£

1Ôª 10Ôª 50Ôª





ÈÏÖ¤Â룺  ÑéÖ¤Âë,¿´²»Çå³þ?Çëµã»÷Ë¢ÐÂÑéÖ¤Âë ±ØÌî



  ÇóÖª ÎÄÕ ÎÄ¿â Lib ÊÓÆµ iPerson ¿Î³Ì ÈÏÖ¤ ×Éѯ ¹¤¾ß ½²×ù Model Center   Code  
»áÔ±   
   
 
     
   
 ¶©ÔÄ
  ¾èÖú
React v16 ÐÂÌØÐÔʵ¼ù
 
  2470  次浏览      29
 2018-6-14
 
±à¼­ÍƼö:
±¾ÎÄÀ´×ÔÓÚÍøÂ磬Ö÷Òª½éÉÜÁËReact v16.0 °æ±¾ÖжÔ×îÐ嵀 Context API ºÍ Ref APIµÈ·½ÃæµÄϸ½ÚµÄ½²½â¼°×ܽᣬϣÍû¶Ô´ó¼ÒµÄÑ§Ï°ÄØ¹ýÓаïÖú¡£

×Ô´ÓÈ¥Äê9ÔÂ·Ý React ÍŶӷ¢²¼ÁË v16.0 °æ±¾¿ªÊ¼£¬µ½18Äê3Ô¸շ¢²¼µÄ v16.3 °æ±¾£¬React Â½ÐøÍÆ³öÁ˶àÏîÖØ°õÐÂÌØÐÔ£¬²¢¸Ä½øÁËÔ­Óй¦ÄÜÖз´À¡ºôÉùºÜ¸ßµÄһЩÎÊÌ⣬ÀýÈç render ·½·¨ÄÚµ¥½Úµã²ã¼¶Ç¶Ì×ÎÊÌ⣬ÌṩÉúÃüÖÜÆÚ´íÎó²¶×½£¬×é¼þÖ¸¶¨ render µ½ÈÎÒâ DOM ½Úµã (Portal) µÈÄÜÁ¦£¬ÒÔ¼°×îÐ嵀 Context API ºÍ Ref API¡£ÎÒÃÇÔÚ¶ÔÒÔÉÏÐÂÌØÐÔ¾­¹ýÒ»¶Îʱ¼äµÄʹÓùýºó£¬Í¨¹ý±¾ÎĽøÐÐһЩϸ½Ú·ÖÏíºÍ×ܽᡣ

Ò»¡¢render ·½·¨ÓÅ»¯

ΪÁË·ûºÏ React µÄ component tree ºÍ diff ½á¹¹Éè¼Æ£¬ÔÚ×é¼þµÄ render() ·½·¨Öж¥²ã±ØÐë°ü¹üΪµ¥½Úµã£¬Òò´Ëʵ¼Ê×é¼þÉè¼ÆºÍʹÓÃÖÐ×ÜÊÇÐèҪעÒâǶÌ׺óµÄ²ã¼¶±äÉÕâÊÇ React µÄÒ»¸ö¾­³£±»ÈËÚ¸²¡µÄÎÊÌâ¡£±ÈÈçÒÔϵÄÄÚÈݽṹ¾Í±ØÐëÔÙǶÌ×Ò»¸ö div ʹÆä±äΪµ¥½Úµã½øÐзµ»Ø£º

render() {
return (
<div>
×¢£º
<p>²úƷ˵Ã÷Ò»</p>
<p>²úƷ˵Ã÷¶þ</p>
</div>
);
}

ÏÖÔÚÔÚ¸üРv16 °æ±¾ºó£¬Õâ¸öÎÊÌâÓÐÁËеĸĽø£¬render ·½·¨¿ÉÒÔÖ§³Ö·µ»ØÊý×éÁË£º

render() {
return [
"×¢:",
<p key="t-1">²úƷ˵Ã÷Ò»</h2>,
<p key="t-2">²úƷ˵Ã÷¶þ</h2>,
];
}

ÕâÑùȷʵÉÙÁËÒ»²ã£¬µ«´ó¼ÒÓÖ¼ÌÐø·¢ÏÖ´úÂ뻹ÊDz»¹»¼ò½à¡£Ê×ÏÈ TEXT ½ÚµãÐèÒªÓÃÒýºÅ°üÆðÀ´£¬Æä´ÎÓÉÓÚÊÇÊý×飬ÿÌõÄÚÈݵ±È»»¹ÐèÒªÌí¼Ó¶ººÅ·Ö¸ô£¬ÁíÍâ element ÉÏ»¹ÐèÒªÊÖ¶¯¼Ó key À´¸¨Öú diff¡£¸øÈ˸оõ¾ÍÊDz»ÏñÔÚд JSX ÁË¡£

ÓÚÊÇ React v16.2 ³ÃÈÈ´òÌú£¬ÌṩÁ˸üÖ±½ÓµÄ·½·¨£¬¾ÍÊÇ Fragment:

render() {
return (
<React.Fragment>
×¢£º
<p>²úƷ˵Ã÷Ò»</p>
<p>²úƷ˵Ã÷¶þ</p>
</React.Fragment>
);
}

¿ÉÒÔ¿´µ½ÊÇÒ»¸öÕý³£µ¥½Úµãд·¨£¬Ö±½Ó°ü¹üÀïÃæµÄÄÚÈÝ¡£µ«ÊÇ Fragment ±¾Éí²¢²»»á²úÉúÕæÊµµÄ DOM ½Úµã£¬Òò´ËÒ²²»»áµ¼Ö²㼶ǶÌ×Ôö¼Ó¡£

ÁíÍâ Fragment »¹ÌṩÁËÐ嵀 JSX ¼òд·½Ê½ <></>£º

render() {
return (
<>
×¢£º
<p>²úƷ˵Ã÷Ò»</p>
<p>²úƷ˵Ã÷¶þ</p>
</>
);}

¿´ÉÏÈ¥ÊÇ·ñÊæ·þ¶àÁË¡£²»¹ý×¢ÒâÈç¹ûÐèÒª¸ø Fragment Ìí¼Ó key prop£¬ÊDz»Ö§³ÖʹÓüòдµÄ£¨ÕâÒ²ÊÇ Fragment Ψһ»áÓöµ½ÐèÒªÌí¼ÓpropsµÄÇé¿ö£©:

<dl>
{props.items.map(item => (
// Òª´«keyÓò»ÁË <></>
<Fragment key={item.id}>
<dt>{item.term}</dt>
<dd>{item.description}</dd>
</Fragment>
))}
</dl>

¶þ¡¢´íÎó±ß½ç (Error Boundaries)

´íÎó±ß½çÊÇÖ¸ÒÔÔÚ×é¼þÉ϶¨Òå componentDidCatch ·½·¨µÄ·½Ê½À´´´½¨Ò»¸öÓдíÎó²¶×½¹¦ÄܵÄ×é¼þ£¬ÔÚÆäÄÚǶÌ×µÄ×é¼þÔÚÉúÃü¹ý³ÌÖз¢ÉúµÄ´íÎ󶼻ᱻÆä²¶×½µ½£¬¶ø²»»áÉÏÉýµ½Íⲿµ¼ÖÂÕû¸öÒ³ÃæºÍ×é¼þÊ÷Òì³£ crash¡£

ÀýÈçÏÂÃæµÄÀý×Ó¾ÍÊÇͨ¹ýÒ»¸ö ErrorBoundary ×é¼þ¶ÔÆäÄÚµÄÄÚÈݽøÐб£»¤ºÍ´íÎó²¶×½£¬²¢ÔÚ·¢Éú´íÎóʱ½øÐжµµ×µÄUIչʾ£º

class ErrorBoundary extends Component {
constructor(props) {
super(props);
this.state = { error: null };
}
componentDidCatch(error,
{componentStack}
) {
this.setState({
error,
componentStack,
});
}
render() {
if (this.state.error) {
return (
<>
<h1>±¨´íÁË.</h1>
<ErrorPanel {...this.state} />
</>
);
}
return this.props.children;
}
}
export default function App(){
return (
<ErrorBoundary>
<Content />
</ErrorBoundary>
);
}

ÐèҪעÒâµÄÊÇ´íÎó±ß½çÖ»Äܲ¶×½ÉúÃüÖÜÆÚÖеĴíÎó (willMount / render µÈ·½·¨ÄÚ)¡£ÎÞ·¨²¶×½Òì²½µÄ¡¢Ê¼þ»Øµ÷ÖеĴíÎó£¬Òª²¶×½ºÍ¸²¸ÇËùÓг¡¾°ÒÀÈ»ÐèÒªÅäºÏ window.onerror¡¢Promise.catch¡¢ try/catch µÈ·½Ê½¡£

Èý¡¢React.createPortal()

Õâ¸ö API ÊÇÓÃÀ´½«²¿·ÖÄÚÈÝ·ÖÀëʽµØ render µ½Ö¸¶¨µÄ DOM ½ÚµãÉÏ¡£²»Í¬ÓÚʹÓà ReactDom.render д´½¨Ò»¸ö DOM tree µÄ·½Ê½£¬¶ÔÓÚҪͨ¹ý createPortal() ¡°·ÖÀ롱³öÈ¥µÄÄÚÈÝ£¬Æä¼äµÄÊý¾Ý´«µÝ£¬ÉúÃüÖÜÆÚ£¬ÉõÖÁʼþðÅÝ£¬ÒÀÈ»´æÔÚÓÚÔ­±¾µÄ³éÏó×é¼þÊ÷½á¹¹µ±ÖС£

class Creater extends Component {
render(){
return (
<div onClick={() =>
alert("clicked!")
}>
<Portal>
<img src={myImg} />
</Portal>
</div>
);
}
}
class Portal extends Component {
render(){
const node = getDOMNode();
return createPortal(
this.props.children,
node
);
}
}

ÀýÈçÒÔÉÏ´úÂ룬<Creater> ͨ¹ý <Portal> °ÑÀïÃæµÄ <img > ÄÚÈÝäÖȾµ½ÁËÒ»¸ö¶ÀÁ¢µÄ½ÚµãÉÏ¡£ÔÚʵ¼ÊµÄ DOM ½á¹¹ÖУ¬img ÒѾ­ÍÑÀëÁË Creater ±¾ÉíµÄ DOM Ê÷´æÔÚÓÚÁíÒ»¸ö¶ÀÁ¢½Úµã¡£µ«µ±µã»÷ img ʱ£¬ÈÔÈ»¿ÉÒÔÉñÆæµÄ´¥·¢µ½ Creater ÄÚµÄ div É쵀 onclick ʼþ¡£ÕâÀïʵ¼ÊÒÀÀµÓÚ React ´úÀíºÍÖØÐ´ÁËÕûÌ×ʼþϵͳ£¬ÈÃÕû¸ö³éÏó×é¼þÊ÷µÄÂß¼­µÃÒÔ±£³Öͬ²½¡£

ËÄ¡¢Context API

ÒÔǰµÄ°æ±¾ÖÐ Context API ÊÇ×÷Ϊδ¹«¿ªµÄʵÑéÐÔ¹¦ÄÜ´æÔڵģ¬Ëæ×ÅÔ½À´Ô½¶àµÄÉùÒôÒªÇó¶ÔÆä½øÐÐÍêÉÆ£¬ÔÚ v16.3 °æ±¾£¬React ÍŶÓÖØÐÂÉè¼Æ²¢·¢²¼ÁËеĹٷ½ Context API¡£

ʹÓà Context API ¿ÉÒÔ¸ü·½±ãµÄÔÚ×é¼þÖд«µÝºÍ¹²ÏíijЩ "È«¾Ö" Êý¾Ý£¬ÕâÊÇΪÁ˽â¾öÒÔÍù×é¼þ¼ä¹²Ïí¹«¹²Êý¾ÝÐèҪͨ¹ý¶àÓàµÄ props ½øÐвã²ã´«µÝµÄÎÊÌâ (props drilling)¡£±ÈÈçÒÔÏ´úÂ룺

const HeadTitle = (props) => {
return (
<Text>
{props.lang.title}
</Text>;
);
};
// Öмä×é¼þ
const Head = (props) => {
return (
<div>
<HeadTitle lang={props.lang} />
</div>
);
};
class App extends React.Component {
render() {
return (
<Head lang={this.props.lang} />;
);
}
}
export default App = connect((state) => {
return {
lang:state.lang
}
})(App);

ÎÒÃÇΪÁËʹÓÃÒ»¸öÓïÑÔ°ü£¬°ÑÓïÑÔÅäÖô洢µ½Ò»¸ö store Àͨ¹ý Redux connect µ½¶¥²ã×é¼þ£¬È»¶ø½ö½öÊÇ×îµ×¶ËµÄ×Ó×é¼þ²ÅÐèÒªÓõ½¡£ÎÒÃÇÒ²²»¿ÉÄÜΪÿ¸ö×é¼þ¶¼µ¥¶À¼ÓÉÏ connect£¬Õâ»áÔì³ÉÊý¾ÝÇý¶¯¸üеÄÖØ¸´ºÍ²»¿Éά»¤¡£Òò´ËÖмä×é¼þÐèÒªÒ»²ã²ã²»¶Ï´«µÝÏÂÈ¥£¬¾ÍÊÇËùνµÄ props drilling¡£

¶ÔÓÚÕâÖÖÈ«¾Ö¡¢²»³£Ð޸ĵÄÊý¾Ý¹²Ïí£¬¾Í±È½ÏÊʺÏÓà Context API À´ÊµÏÖ£º

Ê×ÏȵÚÒ»²½£¬ÀàËÆ store£¬ÎÒÃÇ¿ÉÒÔÏÈ´´½¨Ò»¸ö Context£¬²¢¼ÓÈëĬÈÏÖµ£º

const LangContext = React.createContext({
title:"ĬÈϱêÌâ"
});

È»ºóÔÚ¶¥²ãͨ¹ý Provider Ïò×é¼þÊ÷Ìṩ Context µÄ·ÃÎÊ¡£ÕâÀï¿ÉÒÔͨ¹ý´«Èë value ÐÞ¸Ä Context ÖеÄÊý¾Ý£¬µ±value±ä»¯µÄʱºò£¬Éæ¼°µÄ Consumer ÄÚÕû¸öÄÚÈݽ«ÖØÐ render£º

class App extends React.Component {
render() {
return (
<LangContext.Provider
value={this.state.lang}
>
<Head />
</LangContext.Provider>
);
}
}

ÔÚÐèҪʹÓÃÊý¾ÝµÄµØ·½£¬Ö±½ÓÓà Context.Consumer °ü¹ü£¬ÀïÃæ¿ÉÒÔ´«ÈëÒ»¸ö render º¯Êý£¬Ö´ÐÐʱ´ÓÖÐÈ¡µÃ Context µÄÊý¾Ý¡£

const HeadTitle = (props) => {
return (
<LangContext.Consumer>
{lang =>
<Text>{lang.title}</Text>
}
</LangContext.Consumer>
);
};

Ö®ºóµÄÖмä×é¼þÒ²²»ÔÙÐèÒª²ã²ã´«µÝÁË£¬ÉÙÁ˺ܶà props£¬¼õÉÙÁËÖмä©´«µ¼Ö³ö´í£¬´úÂëÒ²¸ü¼ÓÇåˬ£º

// Öмä×é¼þ
const Head = () => {
return (
<div>
<HeadTitle />
</div>
);
};

ÄÇô¿´ÁËÉÏÃæµÄÀý×Ó£¬ÎÒÃÇÊÇ·ñ¿ÉÒÔÖ±½ÓʹÓà Context API À´´úÌæµôËùÓеÄÊý¾Ý´«µÝ£¬°üÀ¨È¥µô redux ÕâЩÊý¾Ýͬ²½ library ÁË£¿Æäʵ²¢²»ºÏÊÊ¡£Ç°ÃæÒ²ÓÐÌáµ½£¬Context API Ó¦¸ÃÓÃÓÚÐèҪȫ¾Ö¹²ÏíÊý¾ÝµÄ³¡¾°£¬²¢ÇÒÊý¾Ý×îºÃÊDz»ÓÃÆµ·±¸ü¸ÄµÄ¡£ÒòΪ×÷ΪÉÏ²ã´æÔÚµÄ Context£¬ÔÚÊý¾Ý±ä»¯Ê±£¬ÈÝÒ×µ¼ÖÂËùÓÐÉæ¼°µÄ Consumer ÖØÐ render¡£

±ÈÈçÏÂÃæÕâ¸öÀý×Ó£º

render() {
return (
<Provider value={{
title:"my title"
}} >
<Content />
</Provider>
);
}

ʵ¼Êÿ´Î render µÄʱºò£¬ÕâÀïµÄ value ¶¼ÊÇ´«ÈëÒ»¸öеĶÔÏó¡£Õ⽫ºÜÈÝÒ×µ¼ÖÂËùÓÐµÄ Consumer ¶¼ÖØÐÂÖ´ÐÐ render Ó°ÏìÐÔÄÜ¡£

Òò´Ë²»½¨ÒéÀÄÓà Context£¬¶ÔÓÚijЩ·ÇÈ«¾ÖµÄÒµÎñÊý¾Ý£¬Ò²²»½¨Òé×÷Ϊȫ¾Ö Context ·Åµ½¶¥²ãÖй²Ïí£¬ÒÔÃâµ¼Ö¹ý¶àµÄ Context ǶÌ×ºÍÆµ·±ÖØÐÂäÖȾ¡£

Îå¡¢Ref API

³ýÁË Context API Í⣬v16.3 »¹ÍƳöÁËÁ½¸öÐ嵀 Ref API£¬ÓÃÀ´ÔÚ×é¼þÖиü·½±ãµÄ¹ÜÀíºÍʹÓà ref¡£

ÔÚ´Ë֮ǰÏÈ¿´Ò»ÏÂÎÒÃÇ֮ǰʹÓà ref µÄÁ½ÖÖ·½·¨¡£

// stringÃüÃû»ñÈ¡
componentDidMount(){
console.log(this.refs.input);
}
render() {
return (
<input
ref="input"
/>
);
}

// callback »ñÈ¡
render() {
return (
<input
ref={el => {this.input = el;}}
/>
);
}

ǰһÖÖ string µÄ·½Ê½±È½Ï¾ÖÏÞ£¬²»·½±ãÓÚ¶à×é¼þ¼äµÄ´«µÝ»ò¶¯Ì¬»ñÈ¡¡£ºóÒ»ÖÖ callback ·½·¨ÊÇ֮ǰ±È½ÏÍÆ¼öµÄ·½·¨¡£µ«ÊÇдÆðÀ´ÂÔÏÔÂé·³£¬¶øÇÒ update ¹ý³ÌÖÐÓз¢ÉúÇå³ý¿ÉÄÜ»áÓжà´Îµ÷Óà (callback ÊÕµ½ null)¡£

ΪÁËÌáÉýÒ×ÓÃÐÔ£¬ÐÂ°æ±¾ÍÆ³öÁË CreateRef API À´´´½¨Ò»¸ö ref object, ´«µÝµ½ component µÄ ref ÉÏÖ®ºó¿ÉÒÔÖ±½Ó»ñµÃÒýÓãº

constructor(props) {
super(props);
this.input = React.createRef();
}
componentDidMount() {
console.log(this.input);
}
render() {
return <input ref={this.input} />;
}

ÁíÍ⻹ÌṩÁË ForwardRef API À´¸¨Öú¼ò»¯Ç¶Ì××é¼þ¡¢component ÖÁ element ¼äµÄ ref ´«µÝ£¬±ÜÃâ³öÏÖ this.ref.ref.ref µÄÎÊÌâ¡£

ÀýÈçÎÒÃÇÓÐÒ»¸ö°ü×°¹ýµÄ Button ×é¼þ£¬Ïë»ñÈ¡ÀïÃæÕæÕýµÄ button DOM element£¬±¾À´ÐèÒªÕâÑù×ö£º

class MyButton extends Component {
constructor(props){
super(props);
this.buttonRef = React.createRef();
}
render(){
return (
<button ref={this.buttonRef}>
{props.children}
</button>
);
}
}
class App extends Component {
constructor(props){
super(props);
this.myRef = React.createRef();
}
componentDidComponent{
// ͨ¹ýrefÒ»²ã²ã·ÃÎÊ
console.log(this.myRef.buttonRef);
}
render(){
return (
<MyButton ref={this.myRef}>
Press here
</MyButton>
);
}
}

ÕâÖÖ³¡¾°Ê¹Óà forwardRef API µÄ·½Ê½×öÒ»¸ö¡°´©Í¸¡±£¬¾ÍÄܼò±ãÐí¶à:

import { createRef, forwardRef } from "react";
const MyButton = forwardRef((props, ref) => (
<button ref={ref}>
{props.children}
</button>
));
class App extends Component {
constructor(props){
super(props);
this.realButton = createRef();
}
componentDidComponent{
//Ö±½ÓÄõ½ inner element ref
console.log(this.realButton);
}
render(){
return (
<MyButton ref={this.realButton}>
Press here
</MyButton>
);
}
}

×ܽá

ÒÔÉϾÍÊÇ React v16 ·¢²¼ÒÔÀ´¼¸¸ö±È½ÏÖØÒªºÍÓÐÓõÄÐÂÌØÐÔ£¬ÓÅ»¯µÄͬʱҲ´øÀ´ÁË¿ª·¢ÌåÑéµÄÌáÉý¡£ÁíÍâ v16 ¶Ô±È֮ǰ°æ±¾»¹Óв»´íµÄ°ü´óС½µµÍ£¬Ò²ÊǷdz£¾ßÓÐÓÅÊÆµÄ£º

³ý´ËÖ®Í⣬ÏëÒªÁ˽â¸ü¶àµÄһЩ±ä¸ü±ÈÈçÉúÃüÖÜÆÚµÄ¸üР(getDerivedStateFromProps, getSnapshotBeforeUpdate) ºÍ SSR µÄÓÅ»¯ (hydrate)£¬ÒÔ¼°¼´½«ÍƳöµÄ React Fiber (async render) ¶¯Ïò£¬¿ÉÒÔµã»÷²é¿´Ô­ÎÄÁ˽â¸ü¶àµÄ¹Ù·½ÐÅÏ¢¡£

Õâô¶à¼¤¶¯ÈËÐĵÄÌØÐÔ£¬Èç¹ûÄ㻹ÔÚÓà v15 ÉõÖÁ¾É°æ£¬¾Í¸Ï¿ìÉý¼¶ÌåÑé°É£¡

   
2470 ´Îä¯ÀÀ       29
Ïà¹ØÎÄÕÂ

Éî¶È½âÎö£ºÇåÀíÀôúÂë
ÈçºÎ±àд³öÓµ±§±ä»¯µÄ´úÂë
ÖØ¹¹-ʹ´úÂë¸ü¼ò½àÓÅÃÀ
ÍŶÓÏîÄ¿¿ª·¢"±àÂë¹æ·¶"ϵÁÐÎÄÕÂ
Ïà¹ØÎĵµ

ÖØ¹¹-¸ÄÉÆ¼ÈÓдúÂëµÄÉè¼Æ
Èí¼þÖØ¹¹v2
´úÂëÕû½àÖ®µÀ
¸ßÖÊÁ¿±à³Ì¹æ·¶
Ïà¹Ø¿Î³Ì

»ùÓÚHTML5¿Í»§¶Ë¡¢Web¶ËµÄÓ¦Óÿª·¢
HTML 5+CSS ¿ª·¢
ǶÈëʽC¸ßÖÊÁ¿±à³Ì
C++¸ß¼¶±à³Ì