<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ??一站式輕松地調用各大LLM模型接口,支持GPT4、智譜、豆包、星火、月之暗面及文生圖、文生視頻 廣告
                ## 1.Context(上下文) * 在某些場景下,你想在整個組件樹中傳遞數據,但卻不想手動地在每一層傳遞屬性。你可以直接在 React 中使用強大的`context`API解決上述問題 * 在一個典型的 React 應用中,數據是通過 props 屬性自上而下(由父及子)進行傳遞的,但這種做法對于某些類型的屬性而言是極其繁瑣的(例如:地區偏好,UI 主題),這些屬性是應用程序中許多組件都需要的。Context 提供了一種在組件之間共享此類值的方式,而不必顯式地通過組件樹的逐層傳遞 props ![contextapi](http://img.zhufengpeixun.cn/contextapi.gif) ### 1.1 類組件使用 ~~~ import React from 'react'; import ReactDOM from 'react-dom'; let ThemeContext = React.createContext(); class Title extends React.Component { static contextType = ThemeContext render() { return ( <div style={{ border: `5px solid ${this.context.color}` }}> Title </div> ) } } class Header extends React.Component { static contextType = ThemeContext render() { return ( <div style={{ border: `5px solid ${this.context.color}` }}> Header <Title /> </div> ) } } class Content extends React.Component { static contextType = ThemeContext render() { return ( <div style={{ border: `5px solid ${this.context.color}` }}> Content <button onClick={() => this.context.changeColor('red')}>變紅</button> <button onClick={() => this.context.changeColor('green')}>變綠</button> </div> ) } } class Main extends React.Component { static contextType = ThemeContext render() { return ( <div style={{ border: `5px solid ${this.context.color}` }}> Main <Content /> </div> ) } } class Panel extends React.Component { state = { color: 'green' } changeColor = (color) => { this.setState({ color }); } render() { let value = { color: this.state.color, changeColor: this.changeColor }; //Provider提供者,它負責向下層所有的組件提供數據value return ( <ThemeContext.Provider value={value}> <div style={{ border: `5px solid ${this.state.color}`, width: 300 }}> Panel <Header /> <Main /> </div> </ThemeContext.Provider> ) } } ReactDOM.render(<Panel />, document.getElementById('root')); ~~~ ### 1.2 函數組件使用 ~~~ import React, { Component } from 'react'; import ReactDOM from 'react-dom'; let ThemeContext = React.createContext('theme'); class Header extends Component { render() { return ( <ThemeContext.Consumer> { value => ( <div style={{ border: `5px solid ${value.color}`, padding: 5 }}> header <Title /> </div> ) } </ThemeContext.Consumer> ) } } class Title extends Component { static contextType = ThemeContext; render() { return ( <ThemeContext.Consumer> { value => ( <div style={{border: `5px solid ${value.color}` }}> title </div> ) } </ThemeContext.Consumer> ) } } class Main extends Component { static contextType = ThemeContext; render() { return ( <ThemeContext.Consumer> { value => ( <div style={{ border: `5px solid ${value.color}`, margin: 5, padding: 5 }}> main <Content /> </div> ) } </ThemeContext.Consumer> ) } } class Content extends Component { static contextType = ThemeContext; render() { return ( <ThemeContext.Consumer> { value => ( <div style={{border: `5px solid ${value.color}`, padding: 5 }}> Content <button onClick={() =>value.changeColor('red')} style={{color:'red'}}>紅色</button> <button onClick={() => value.changeColor('green')} style={{color:'green'}}>綠色</button> </div> ) } </ThemeContext.Consumer> ) } } class Page extends Component { constructor() { super(); this.state = { color: 'red' }; } changeColor = (color) => { this.setState({ color }) } render() { let contextVal = {changeColor: this.changeColor,color:this.state.color }; return ( <ThemeContext.Provider value={contextVal}> <div style={{margin:'10px', border: `5px solid ${this.state.color}`, padding: 5, width: 200 }}> page <Header /> <Main /> </div> </ThemeContext.Provider> ) } } ReactDOM.render(<Page />, document.querySelector('#root')); ~~~ ### 1.3 函數組件實現 ~~~ function createContext() { let value; class Provider extends React.Component { constructor(props) { super(props); value = props.value this.state = {}; } static getDerivedStateFromProps(nextProps, prevState) { value = nextProps.value; return {}; } render() { return this.props.children; } } class Consumer extends React.Component { constructor(props) { super(props); } render() { return this.props.children(value); } } return { Provider, Consumer } } let ThemeContext = createContext('theme'); ~~~ ## 3\. 高階組件 * 高階組件就是一個函數,傳給它一個組件,它返回一個新的組件 * 高階組件的作用其實就是為了組件之間的代碼復用 ~~~ const NewComponent = higherOrderComponent(OldComponent) ~~~ ### 3.1 日志組件 #### 3.1 手工實現 ~~~ import React, { Component } from 'react'; import ReactDOM from 'react-dom'; class App extends Component { componentWillMount() { this.start = Date.now(); } componentDidMount() { console.log((Date.now() - this.start) + 'ms') } render() { return <div>App</div> } } ReactDOM.render(<App />, document.getElementById('root')); ~~~ #### 3.2 高階組件 ~~~ import React,{Component} from 'react'; import ReactDOM from 'react-dom'; const logger = (WrappedComponent) => { class LoggerComponent extends Component { componentWillMount(){ this.start = Date.now(); } componentDidMount(){ console.log((Date.now() - this.start)+'ms') } render () { return <WrappedComponent /> } } return LoggerComponent; } let Hello = logger(props=><h1>hello</h1>); ReactDOM.render(<Hello />, document.getElementById('root')); ~~~ ### 3.2 多層高階組件 #### 3.2.1 從localStorage中加載 ~~~ import React,{Component} from 'react'; import ReactDOM from 'react-dom'; const fromLocal = (WrappedComponent,name) =>{ class NewComponent extends Component{ constructor(){ super(); this.state = {value:null}; } componentWillMount(){ let value = localStorage.getItem(name); this.setState({value}); } render(){ return <WrappedComponent value={this.state.value}/> } } return NewComponent; } const UserName = ({value})=>( <input defaultValue = {value}/> ) const UserNameFromLocal = fromLocal(UserName,'username'); ReactDOM.render(<UserNameFromLocal />, document.getElementById('root')); ~~~ #### 3.2.2 從ajax中加載 ~~~ import React,{Component} from 'react'; import ReactDOM from 'react-dom'; const fromLocal = (WrappedComponent,name) =>{ class NewComponent extends Component{ constructor(){ super(); this.state = {id:null}; } componentWillMount(){ let id = localStorage.getItem(name); this.setState({id}); } render(){ return <WrappedComponent id={this.state.id}/> } } return NewComponent; } const fromAjax = (WrappedComponent) =>{ class NewComponent extends Component{ constructor(){ super(); this.state = {value:{}}; } componentDidMount(){ fetch(`/${this.props.id}.json`).then(response=>response.json()).then(value=>{ this.setState({value}); }); } render(){ return <WrappedComponent value={this.state.value}/> } } return NewComponent; } const UserName = ({value})=>{ return <input defaultValue = {value.username}/>; } const UserNameFromAjax = fromAjax(UserName); const UserNameFromLocal = fromLocal(UserNameFromAjax,'id'); ReactDOM.render(<UserNameFromLocal />, document.getElementById('root')); ~~~ translate.json ~~~ { "zhangsan": "張三" } ~~~ ## 4\. render props * [render-props](https://zh-hans.reactjs.org/docs/render-props.html) * `render prop`是指一種在 React 組件之間使用一個值為函數的 prop 共享代碼的簡單技術 * 具有 render prop 的組件接受一個函數,該函數返回一個 React 元素并調用它而不是實現自己的渲染邏輯 * render prop 是一個用于告知組件需要渲染什么內容的函數 prop * 這也是邏輯復用的一種方式 ~~~ <DataProvider render={data => ( <h1>Hello {data.target}</h1> )}/> ~~~ ### 4.1 原生實現 ~~~ class MouseTracker extends React.Component { constructor(props) { super(props); this.state = { x: 0, y: 0 }; } handleMouseMove = (event) => { this.setState({ x: event.clientX, y: event.clientY }); } render() { return ( <div onMouseMove={this.handleMouseMove}> <h1>移動鼠標!</h1> <p>當前的鼠標位置是 ({this.state.x}, {this.state.y})</p> </div> ); } } ~~~ ### 4.2 children ~~~ class MouseTracker extends React.Component { constructor(props) { super(props); this.state = { x: 0, y: 0 }; } handleMouseMove = (event) => { this.setState({ x: event.clientX, y: event.clientY }); } render() { return ( <div onMouseMove={this.handleMouseMove}> {this.props.children(this.state)} </div> ); } } ReactDOM.render(< MouseTracker > { props=>( <> <h1>移動鼠標!</h1> <p>當前的鼠標位置是 ({props.x}, {props.y})</p> </> ) } </ MouseTracker>, document.getElementById('root')); ~~~ ### 4.3 render屬性 ~~~ import React,{Component} from 'react'; import ReactDOM from 'react-dom'; class MouseTracker extends React.Component { constructor(props) { super(props); this.state = { x: 0, y: 0 }; } handleMouseMove = (event) => { this.setState({ x: event.clientX, y: event.clientY }); } render() { return ( <div onMouseMove={this.handleMouseMove}> {this.props.render(this.state)} </div> ); } } ReactDOM.render(< MouseTracker render={params=>( <> <h1>移動鼠標!</h1> <p>當前的鼠標位置是 ({params.x}, {params.y})</p> </> )} />, document.getElementById('root')); ~~~ ### 4.4 HOC ~~~ class MouseTracker extends React.Component { constructor(props) { super(props); this.state = { x: 0, y: 0 }; } handleMouseMove = (event) => { this.setState({ x: event.clientX, y: event.clientY }); } render() { return ( <div onMouseMove={this.handleMouseMove}> {this.props.render(this.state)} </div> ); } } function withMouse(Component){ return ( (props)=><MouseTracker render={mouse=><Component {...props} {...mouse}/>}/> ) } let App = withMouse(props=>( <> <h1>移動鼠標!</h1> <p>當前的鼠標位置是 ({props.x}, {props.y})</p> </> )); ReactDOM.render(<App/>, document.getElementById('root')); ~~~ ## 5\. 插槽(Portals) * Portals 提供了一種很好的方法,將子節點渲染到父組件 DOM 層次結構之外的 DOM 節點。 ~~~ ReactDOM.createPortal(child, container) ~~~ * 第一個參數(child)是任何可渲染的 React 子元素,例如一個元素,字符串或 片段(fragment) * 第二個參數(container)則是一個 DOM 元素 index.html ~~~ <div id="modal-root"></div> ~~~ index.js ~~~ import React,{Component} from 'react'; import ReactDOM from 'react-dom'; import './modal.css'; class Modal extends Component{ constructor() { super(); this.modal=document.querySelector('#modal-root'); } render() { return ReactDOM.createPortal(this.props.children,this.modal); } } class Page extends Component{ constructor() { super(); this.state={show:false}; } handleClick=() => { this.setState({show:!this.state.show}); } render() { return ( <div> <button onClick={this.handleClick}>顯示模態窗口</button> { this.state.show&&<Modal> <div id="modal" className="modal"> <div className="modal-content" id="modal-content"> 內容 <button onClick={this.handleClick}>關閉</button> </div> </div> </Modal> } </div> ) } } ReactDOM.render(<Page/>,document.querySelector('#root')); ~~~ modal.css ~~~ .modal{ position: fixed; left:0; top:0; right:0; bottom:0; background: rgba(0,0,0,.5); display: block; } @keyframes zoom{ from{transform:scale(0);} to{transform:scale(1);} } .modal .modal-content{ width:50%; height:50%; background: white; border-radius: 10px; margin:100px auto; display:flex; flex-direction: row; justify-content: center; align-items: center; animation: zoom .6s; } ~~~ ~~~ import React from 'react'; /** 寫一個函數,然后參數是一個組件 高階組件用來解決組件間的邏輯復用問題 高階 高階函數 函數可以作為函數的參數或者返回值,這就叫同階函數 高階 高階組件 組件可以作為函數的參數或者返回值,這就叫同階組件 */ function withLogger(WrappedComponent){ return class extends React.Component{ componentWillMount(){ this.start = Date.now(); } componentDidMount(){ console.log(`此組件渲染一共花了${Date.now()-this.start}ms`); } render(){ return <WrappedComponent/> } }; } let Hello = ()=><div>hello</div>; Hello = withLogger(Hello); export default Hello; ~~~ ~~~ import React from 'react'; class Form extends React.Component{ render(){ return ( <form> <UserName/> <Password/> </form> ) } } function fromLocal(WrappedComponent,key){ return class extends React.Component{ constructor(props){ super(props); this.state = {value:''}; } componentWillMount(){ this.setState({ value:localStorage.getItem(key) }); } render(){//this.state.value = zhangsan return <WrappedComponent value={this.state.value} /> } } } function fromAjax(WrappedComponent){ return class extends React.Component{ constructor(props){ super(props); this.state = {value:''}; } componentWillMount(){ //一方面要從屬性中取值到父組件傳過來的屬性值value let value = this.props.value;//username /username.json fetch(`/${value}.json`).then(res=>res.json()).then(result=>{ console.log(result); this.setState({value:result.value});//result.value=張三 }); } render(){//WrappedComponent=UserName return <WrappedComponent value={this.state.value} /> } } } class UserName extends React.Component{ render(){ return <>用戶名:<input value={this.props.value} /></> } } UserName = fromAjax(UserName); UserName = fromLocal(UserName,'username'); class Password extends React.Component{ render(){ return <>密碼:<input value={this.props.value} onChange={this.props.handleChange}/></> } } Password = fromAjax(Password); Password = fromLocal(Password,'password'); export default Form; ~~~ ![](https://img.kancloud.cn/a1/34/a13452772c6645e7b9593c02b8098047_861x585.png) ~~~ import React,{Component} from 'react'; class MouseTracker extends React.Component{ state = {x:0,y:0} handleMouseMove = (event)=>{ this.setState({ x:event.clientX, y:event.clientY }); } render(){ return ( <div onMouseMove={this.handleMouseMove} > {this.props.render(this.state)} </div> ) } } export default MouseTracker; ~~~ ![](https://img.kancloud.cn/4c/17/4c17b8860e3cf23428842578b6f613a1_1177x649.png) ![](https://img.kancloud.cn/8b/0a/8b0ac370af29a7f9beae31ffbb5e571f_908x686.png) ![](https://img.kancloud.cn/2e/0c/2e0cda090972d6f76cf628aec143dec2_881x405.png)
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看