--- title: React tags: Web Directory, React, JavaScript description: react Learning Notes --- {%hackmd U6g0skbVTIyVdJhvWCgo2Q %} <style> #change-a:link, #change-a:visited{ text-decoration: none; color: #00008B !important; } </style> # <span class="big-title">React</span> - [online react editor](https://codepen.io/pen) - if it have `uncaughtError`, try import reat and reactDOM ```jsx= // Add to the front import React from "https://cdn.skypack.dev/react" import ReactDOM from "https://cdn.skypack.dev/react-dom" ``` > then choose the alternative to get proper import source - some of examples are self-writed, some of them come from W3C, React Document, and Fooish -> see [reference](#Reference) ## <span class="intext-title">Introduction</span> - React is a tool for building UI components. - React using ES6 - [what is ES6?](https://hackmd.io/@yzLin56789/ByBQ3Wdet/%2FmKeI3lVBQgqH730NKXwcXQ#ES6) - ECMAScript 6 -> ECMAScript is used to standardize javascript ### <span class="intext-point">Purpose of React</span> - React seperate development of web to **components** - Not like structure, logic, style, react will put eles belongs to ame components together ## <span class="intext-title">Testing React on Website</span> ```htmlembedded= <head> <script src="https://unpkg.com/react@17/umd/react.development.js" crossorigin></script> <script src="https://unpkg.com/react-dom@17/umd/react-dom.development.js" crossorigin></script> <script src="https://unpkg.com/babel-standalone@6.26.0/babel.js"></script> </head> ``` ### <span class="intext-point">A Complete Example</span> ```jsx= <!DOCTYPE html> <html lang="zh-TW"> <head> <title>Static resource and Testing React</title> <meta charset="utf-8" /> <script src="https://unpkg.com/react@17/umd/react.development.js" crossorigin></script> <script src="https://unpkg.com/react-dom@17/umd/react-dom.development.js" crossorigin></script> <script src="https://unpkg.com/babel-standalone@6.26.0/babel.js"></script> </head> <body> <script type="text/babel"> class Student extends React.Component{ constructor(props){ super(props); this.state = { id: Math.floor(Math.random() * 100), show: (Math.random() > 0.5) ? true : false }; } render(){ return this.state.show ? ( <React.Fragment> <h1>Hello, My name is {this.props.name}</h1> <p>My ID is {this.state.id}</p> </React.Fragment> ) : ( <h1>QQ... You are unlucky, BOYYYYYYY.</h1> ) } } ReactDOM.render(<Student name="Thomas" />, document.getElementById("root")); </script> <div id="root"> <!--space for react--> </div> </body> </html> ``` ## <span class="intext-title">Create React Application</span> ```bash= npx create-react-app simplereactapp ``` - `npx` (node package executor) will execute the package and create a react application on target directory ```bash= cd simplereactapp ``` > cd into it ```bash= npm start ``` > use `npm start`, which start running the react app ### <span class="intext-point">Folder Structure & Architecture</span> - [Reference](https://saurabhshah23.medium.com/react-js-architecture-features-folder-structure-design-pattern-70b7b9103f22) - It includes introduction and analysis about folder structure and application architexture. # <span class="big-title">React Render HTML</span> - The goal of React is to render HTML on web page, the render will include: - HTML code - HTML writen in JSX or use `React.createElement()` method - HTML element ```jsx= const simpleelement = ( <h1>Hello React!</h1> ); ReactDOM.render(simpleelement, document.getElementByID("root")); ``` ## <span class="intext-title">React Element</span> - Basic unit in React - Render an element to DOM ```jsx= const element = <h1>Hello, React!</h1>; ReactDOM.render(element, document.getElementById("root")); ``` > usually, it is only necessary to call `ReactDOM.render()` once in program > The `#root` HTML element will be set to represent this section is under the control of React ### <span class="intext-point">Building an Element</span> - With `React.createElement()` ```javascript= const element = React.createElement( 'h1', {className: 'greeting'}, 'Hello, World!' ); ``` - With `JSX` ```jsx= const element = ( <h1 className="greeting"> Hello, World! </h1> ); ``` # <span class="big-title">JSX</span> - using HTML tags in JS file - JSX is for creating element in React - eles must be **closed** in React - JSX will be compiled as normal JS expression by **Babel** - it will call `React.createElement()` ```jsx= // using JSX const myelement = <h1>I Love JSX!</h1>; ReactDOM.render(myelement, document.getElementById('root')); // without JSX const myelement = React.createElement('h1', {}, 'I do not use JSX!'); ReactDOM.render(myelement, document.getElementById('root')); ``` > it should be noticed that JSX representing **JavaScript expression** > > statements like `if/else` are not allowed - HTML code will only support <strong>ONE</strong> top levle element - using `div` to include multiple element is a good practice ```jsx= const anelement = ( <div> <h1>This is first.</h1> <h1>I am Second one.</h1> </div> ); ``` ## <span class="intext-title">Fragment</span> - using JSX, we need to add a top-level tag - it will cause unnecessary tag in code - for example, dynamic existing list item will be affect since there is a top div tags on it - After React16, `Fragment` was added up for dealing with this question ```jsx= const element = ( <React.Fragment> <td>One for data cell.</td> <td>Second for data cell.</td> </React.Fragment> ); //or const element = ( <> <td>One for data cell.</td> <td>Second for data cell.</td> </> ) ``` ## <span class="intext-title">Expressions</span> - By using `{}`, JSX can write variable, JS expressions in it ```jsx= let a = 10; const conditionele = ( <h1>{ (a) > 10 ? "HI" : "NONO"}</h1> ); ``` > By using ternary expression, conditional expression can be written in JSX > > Or Simply use conditional `if statement` outside - It is also possible to write attr expression ```jsx= const element = <a src={user.homepage}>See introduction</a> ``` ## <span class="intext-title">JS camelCase on attr</span> - JSX have allternative when facing Reserved word in JS - Alternative - `class` -> `className` - `for` -> `htmlFor` ```jsx= <h1 className="input-type">HAHA</h1> ``` - Set Attr with **spread operator** (rest operator) ```jsx= var props = {}; props.foo = x; props.bar = y; var component = <Component {...props} />; // set as default attr var component2 = <Component {...props} foo="Hello" /> ``` ## <span class="intext-title">CSS inline</span> ```jsx= const divStyle = { color: 'blue', backgroundImage: 'url(' + imgUrl + ')' }; function HelloWorldComponent() { return <div style={divStyle}>Hello World!</div>; } function Hello2() { return ( <div style={{color: "blue", backgroundImage: `url (${imgUrl})`}}>Hello</div> ); } ``` - Notice that attribute name should also be **camelCase** - `backgroud-image` -> `backgroundImage` - `font-style` -> `fontStyle` ## <span class="intext-title">Directly set innerHTML</span> - can directly operate innerHTML like normal -> `dangerouslySetInnerHTML` ```jsx= // normal function showContent() { return <h1>{test}</h1> } function createMarkup() { return {__html: 'First &middot; Second'}; } function MyComponent() { return <div dangerouslySetInnerHTML={createMarkup()} />; } ``` > Shoould take an object contained `__html` field >> Since React will do HTML escape for JSX expression, this is dangerous for XSS # <span class="big-title">React Component</span> ``` React Component is set to gain props and return correspoding element ``` > <span class="important">React component is aim to build reuseable component in web application. </span> - Component can be defined as - *function* component - *class* component ```jsx= // function component function Welcome(props) { return <h1>Hello, {this.props.name} !!</h1>; } // Class component class Welcome extends React.Component { // Necessary Method in React Component render(){ return <h1>Hello, {this.props.name}</h1>; } } ``` - A `modulelized` thinking should be used to format your code - it will be an extended spirit from seperating **reusable** component - React use composition thinking, it's different with normal inheritant thinking. - combine some reusable components to make new component on web page - **State & Prop** - Props are params which will be passed into a component via attrs - State are params which **completely owned** by a component - <span class="important">Single Directioin Data Flow</span> - parent state -> child props - it will ensure the renew on parent's state will effect child's props - From above, we konw **any modify on props should be avoid (they are private state of the other -> mostly it will be owned by parents)** ## <span class="intext-title">Render Component</span> - Method `render()` is necessary and only necessary in React Component - component will judge `props` and `status`, the return corresponding content - `render()` should be **pure**, it wont change anything about state, and have no direct interaction with browser. - React element can be 1. normal tag: ```<div />;``` 2. component: ```<Welcome name="Thomas" />``` - React will treat lowercase letter as original html tag - As a Component, the **name** of it should be ==started with uppercase== ### <span class="intext-point">Example</span> ```jsx= // started with uppercase function Welcome(props){ return <h1>Hello, {this.props.name}. </h1>; } ReactDOM.render(<Welcome name="Thomas" />, document.getElementById("root")); ``` ## <span class="intext-title">Mounting & Unmounting</span> - a Component will be **mounted** once it be rendered to DOM - Unmount usually controled by parent ```jsx= // In parent return {this.state.showTimer && <TimerShow showTimer={this.state.showTimer} timerID={this.state.timerID} />} ``` - if we render false in children, it will have no effect to unmount ## <span class="intext-title">Props</span> - a `props` is a simple object which contains attributes and children of JSX - it will be pass when we call a component with JSX such as ```jsx= // render to DOM ReactDOM.render(<Welcome name="Thomas" />, document.getElementById("root")); // in Component, props can be accessed like /*...*/ <h1>Hello, I am {this.props.name} </h1> ``` > for this example, props will contain name which be passed by **JSX -> Babel** - in component, we pass props and get `return` React element ### <span class="intext-point">props.children</span> - it can usually be used by container ```jsx= // props.children will indicate those tags under it function FancyBorder(props) { return ( <div className={'FancyBorder FancyBorder-' + props.color}> {props.children} </div> ); } // A component with a self-defined container function WelcomeDialog() { return ( <FancyBorder color="blue"> <h1 className="Dialog-title"> Welcome </h1> <p className="Dialog-message"> Thank you for visiting our spacecraft! </p> </FancyBorder> ); } // render the component to DOM ReactDOM.render( <WelcomeDialog />, document.getElementById('root') ); ``` ### <span class="intext-point">ReadOnly about Props</span> - Props should be **readonly**, things like modifying props should be avoid. - On that way, React components work like pure function with props ## <span class="intext-title">State</span> - state in component should store time-related data - whether `state` or `props` changed, the component will be [renewed](https://zh-hant.reactjs.org/docs/react-component.html#updating) > on example, it will happend not only the `Student` renewed, but also `Format` renewed (==Student.state -> Format.props==) - initialization about state in constructor should be directly ==assign== - in other methods, `setState()` should be called. ### <span class="intext-point">`setState()`</span> ```javascript= setState(updater, [callback]); // example this.setState({ name: "Thomas" }) ``` > change of state will trigger renew > > callback can be some function called after the setState complete -> when callback function is called, this will ensure the state change has been done - This method is used to renew state in funcitons (except `constructor`) - constructor should directly use `this.state` - setState isn't confirm **immediately** renew - state change will be lined up in queue -> for better preformance ! - means it's not proper to read/use state after setState - For immediately renew state, use <span class="important">updater function</span> ```javascript= this.setState((prevState) => { return {quantity: prevState.quantity + 1}; }); this.setState((prevState, props)) => { couter: prevState.counter + props.increment }); ``` ### <span class="intext-point">A complete example about state</span> ```jsx= import React from 'react'; import ReactDOM from 'react-dom'; import './index.css'; /*React Components */ // TODO: A stateless component are presented // ! which means to show single-direction data flow // ! (up.state -> down.props) /* It has no idea where the props come from.*/ function FormatIntro(props){ return <p>Hello, I am {props.sayHello}</p> } // TODO: A stateful component has local states. // ! this state are completely private // ! and should be modify via this.setState() class Student extends React.Component { constructor(props){ super(props); // Component with state is stateful component // Directly assign state in constructor this.state = { sayHello: "", timerID: 0 }; /* data which has no relation about data flow can * directly set in class*/ this.now = 0; } // this function will be called by timer pick = () => { if (this.now < this.props.name.length){ let string = this.state.sayHello + this.props.name.charAt(this.now++); // use setState() will rerender component this.setState({sayHello: string}); } else{ this.now = 0; this.setState({sayHello: ""}); } } // Mount & Unmount for component componentDidMount(){ // set a timer when this component mounted to DOM this.setState({ timerID: setInterval(() => this.pick(), 1000)}); } componentWillUnmount(){ clearInterval(this.timerID); } render() { return ( <div> <h2>This is my introduction</h2> <FormatIntro sayHello={this.state.sayHello} /> <p>now Timer ID is: {this.state.timerID}</p> </div> ) } } ReactDOM.render(<Student name="Thomas"/>, document.getElementById("root")); ``` ## <span class="intext-title">[Life-Cycle Method](https://zh-hant.reactjs.org/docs/react-component.html#the-component-lifecycle)</span> - Multiple life-cycle methods have been added to React Component, it will be called - when Component **mouting** to DOM - when Component get **renew** - when Component **unmounted** from DOM ### <span class="intext-point">Common Methods</span> - Mounting 1. constructor() 2. render() 3. componentDidMount() - Renew 1. render() 2. componentDidUpdate() - Unmounting - componentWillUnmount() ### <span class="intext-point">constructor</span> ```jsx= class Students extends React.Component { constructor(props){ super(props); this.state = { //... } this.selfNewMethod = this.selfNewMethod.bind(this); } selfNewMethod(){ this.updateList(); } } ``` > `super(props)` should be called before any initialization, or `this.props` will be undefined > A `bind` is necessary for a function to become a method of class > > with **arrow funciton**, we can bind function and declare it at the same time -> `Class Fields` + `arrow function` - Mainly two usage 1. initialize `this.state` 2. bind for `event handler` - see <a href="#related-to-constructor">React Event Handler</a> - Avoid copy props to state - Avoid use `setState` for initialzation - Class Fields + Arrow Function ```jsx= class Student extends React.Component { selfNewMethod = () => { this.updateList(); } } ``` ### <span class="intext-point">static getDerivedStateFromProps()</span> - this function will be called before `render()` - <span class="important">return value is an object of status</span> - passed current props and state in - situation: state are decided by props, it should be renewed when props changed ```jsx= //example static getDerivedStateFromProps(props, state) { if (props.currentVal !== state.prevVal){ return ({ name: "NEW", val: props.currentVal }) } return null; } ``` ### <span class="intext-point">componentDidMount</span> - Good to build subscription - `componentWillUnmount` should cancel those subscription - for example, timer - `setState()` can be called in this method, and have following effect: - trigger another `render` - two render will only renewed once on webbrowser - it will still cause efficiency waste -> carefully use ### <span class="intext-point">componentDidUpdate</span> - Method will be called after every renew - Make comparison in this method - Avoid causing infinity loop between renew # <span class="big-title">React Event Handler</span> <span class="hover-head important">Talk about React Binding<iframe src="https://drive.google.com/file/d/1D3VPReXTnX5jWpksS8YhMhM5hqcpns84/preview" class = "hover-child" width="640" height="480" controls></iframe></span> - For keeping reading, make sure you understand binding event listener to event - [reference MDN](https://developer.mozilla.org/zh-TW/docs/Web/JavaScript/Reference/Global_Objects/Function/bind) - [reference -- fooish](https://www.fooish.com/javascript/this.html#functionprototypebind) - Bind event listener to class - Make it is a method of it - this way, the listener can access **this** in class - <a href="https://hackmd.io/wO7HlPz0Rq6eloUd8yclVQ?view#constructor" target="_self" id="related-to-constructor">see above</a> ```jsx= class Student extends React.Component { constructor(props){ super(props); this.state = { id: Math.floor(Math.random() * 100) } this.handleClickEvent = this.handleClickEvent.bind(this); } handleClickEvent(){ this.updateStudentCard(); } render(){ return <h1 onClick={this.handleClickEvent}>Click Me To Change Color!!</h1> } } ``` ## <span class="intext-title">Event Level</span> - events like `onClick`, `onMouseEnter` - they should be triggered at builtin element -> e.g. `div`, `p`... - if pass on parent, ie pass to a self-defined React component, it will be treated like normoal attr and pass it to `props` - we can use it to pass event handler and access it by `props` in child ```jsx= <p style={this.state.pStyle} onClick={this.props.onClick}> Use parent's handler via props. </p> ``` > this can be related to Lifing State Up (it's invoke a callback function from parents) ## <span class="intext-title">Event & Listener in JSX</span> ``` we can simply add listened to event in JSX ``` - Events in JSX are **camelCase** ```jsx= // Above has bind event listener to class (this) <input type="button" value="Say HET" onClick={this.handleClickEvent} /> ``` - in HTML ```htmlembedded= <input type="button" value="Say HET" onclick="handleClickEvent()" /> ``` ### <span class="intext-point">Synthetic event and Native event</span> - Synthetic Event is built by React to deal with event - Native Event - can be gained by using `event.nativeEvent` ### <span class="intext-point">Use Class Fields to Bind EventListener</span> ```jsx= //... handleClickEvent = () => { this.updateStudentCard(); } /*If need to invoke Synthetic event wrapper*/ handleClickEvent = (e) => { e.preventDefault(); this.updateStudentCard(); } ``` > In this case, `preventDefault` will be used to prevent default operation made by browser like ==click anchor, it will go to href after indicated scripts end==. ### <span class="intext-point">Passing argument to eventlistener</span> ```jsx= <input type="button" value="Say HEY" onClick={() => this.handleClickEvent()} /> // Following two cases will pass event param to listener <input type="button" value="Say HEY" onClick={(e) => this.handleClickEvent(e)} /> <input type="button" value="Say HEY" onClick={this.handleClickEvent} /> // If we want to pass other params to listener <input type="button" value="Say HEY" onClick={(e, otherp) => this.handleClickEvent(e. otherp)} /> ``` # <span class="big-title" id="change-a">[Lifting State Up](https://www.fooish.com/reactjs/lifting-state-up.html)</span> <figure style="width: 50%; float: right; margin: 10px;"> <figcaption style="text-align: center; color: aqua;">Graph about work of Lifiting State Up in <a href="https://www.fooish.com/reactjs/lifting-state-up.html">fooish</a></figcaption> <img src="https://i.imgur.com/FMrFjoD.jpg" /> </figure> - it's a technique with the use of **callback function** - formorly mentioned as Event Level - for commonly state (children are control by same/similar state) - uplift it as a parent state - drop down a parent's callback function to children <div style="clear:both;"></div> ```jsx= // in render <TemperatureInput scale="c" temperature={celsius} onTemperatureChange={this.handleCelsiusChange} /> <TemperatureInput scale="f" temperature={fahrenheit} onTemperatureChange={this.handleFahrenheitChange} /> ``` > `TemperatureInput`s are component that accept different input from user > `this.handleFahrenheitChange`s are callback functions which passed to children to get and process input data # <span class="big-title">Other Rendering</span> - Conditional Rendering - Portal Rendering ## <span class="intext-title">React Conditional Rendering</span> - There are following ways to implement conditional rendering 1. JavaScript - if/else - ternary Operator `? :` 2. JSX - `&&` - ternary Operator `? :` ``` mind JSX is expressions, so if statement isnt usable in it. ``` 3. Render Nothing - return `null` or `false` ### <span class="intext-point">Combinational Example</span> ```jsx= function ComponentFoo(props){ if (props.goShow) { return ( <React.Fragment> <h1>Following show conditional rendering</h1> {props.whichShow ? ( props.isShow && <p>Hello, I am cool</p> ) : ( <p>No, You are not cool.</p> )} </React.Fragment> ) } else{ return null; } } ReactDOM.render(<ComponentFoo goShow="true" whichShow="true" isShow="true" />, document.getElementById("root")); ``` ## <span class="intext-title">ReactDOM Portal</span> - normally, a component will render on its parent controller - with `ReactDOM.createPortal()`, it's able to render components to other container. - it's can be used to solve **z-index**, **layout** problems. ### <span class="intext-point">Format</span> ```jsx= // In Function Component function TestPortal(props){ return ReactDOM.createPortal( <h1>Yes, It work.</h1>, document.getElementById("aside-container") ); } // In Class Component class ClassPortal{ constructor(props){ super(props); } render(){ return ReacrDOM.createPortal( <h1>Yes, it work.</h1>, document.getElementById("aside-container") ); } } ``` > `Portal` should be used when component rendering > > go to other container via Portal # <span class="big-title">React Form Elements Handling</span> - a form element is `controled` - if there is `value` attribute in form element - then this element is under the control of React - a form element is `uncontrolled` - if there has no `value` attribute in form element - then this element will live like normal DOM element - Directly interact with JS DOM API - avoid to use - common form element - `<input>` (including button, checkebox, text...) - `<textarea>` - `<select>` - `<input type="file">` ## <span class="intext-title">Behavior of React Form</span> - element with `value` will be the `controlled element` of React - if it has no implementation about `onChange` event, it cant be control ```jsx= <input type="text" value="This is a fixed text input." /> <input type="text" value="It can accept input from user" onChange={this.handleValueChange} /> ``` ### <span class="intext-point">Event `onChange`</span> - when `value` of form element get changed, React will callback `onChange` event and pass an `event object` - use `event object` to get target information - see [event.target](https://developer.mozilla.org/zh-TW/docs/Web/API/Event/target) - `target.type`, `target.name`, `target.value`... ### <span class="intext-point">Example</span> ```jsx= <input id="use-text" type="text" name="textValue" value={this.state.textValue} onChange={this.handleChange} /> //in event listener handleEvent(e){ //... var value = e.target.value; //... } ``` ## <span class="intext-title">Different way for some element in React</span> - This section will include - `<textarea>` - `<select>` - `<input type="file" />` ### <span class="intext-point">textarea</span> - in **HTML** ```htmlembedded= <textarea cols="12" rows="12"> Default Text </textarea> ``` - in **React** ```jsx= <textarea value={this.state.textValue} onChange={this.handleChange} /> ``` > text value will be put in `value` field in attr ### <span class="intext-point">select</span> - in HTML ```htmlembedded= <select> <option selected disabled>Choose Application</option> <option value="chrome">Chrome</option> <option value="edge">Edge</option> <option value="firefox" selected>FireFox</option> <option value="git">Git</option> </select> ``` > use `selected` attr to show selection - in **React** ```jsx= <select value={this.state.selected} onChange={this.handleChange}> <option selected disabled>Choose Application</option> <option value="chrome">Chrome</option> <option value="edge">Edge</option> <option value="firefox">FireFox</option> <option value="git">Git</option> </select> ``` > use `value` attr in `<select>` to decide selected option ### <span class="intext-point">input type="file"</span> - since **"file"** is **read-only** - this make it a `uncontrolled` element - we use JS file API to get inforamtion ```jsx= // onSubmit event listener handleSubmit(event) { event.preventDefault(); alert( `Selected file - ${this.fileInput.files[0].name}` ); } // bind ref <input type="file" ref={input => { this.fileInput = input; }} /> ``` ## <span class="intext-title">Complete Example</span> ```jsx= class FormTable extends React.Component { constructor(props) { super(props); this.state = { textValue: "Hello", ifChecked: true } this.handleChange = this.handleChange.bind(this); } // use different name to handle onChange by one listener handleChange (e) { var target = e.target; var name = target.name; var type = target.type; var value = (type === "text") ? target.value : target.checked; console.log(value, this.state.ifChecked); this.setState({ [name]: value }) } render(){ const spanStyle= { fontSize: '2em', fonStyle: 'Bold' }; return ( <form> <legend><span style={spanStyle}>Handling Form element</span></legend> // Form element with no onChange implementation // Still under control <p> <label> Unusble: <input id="unuse-text" type="text" value="under controlled of React" /> </label> </p> <p> // Form element with onChange implementation <h2>Controlled Form Element</h2> <label> text input <input id="use-text" type="text" name="textValue" value={this.state.textValue} onChange={this.handleChange} /> </label> <label> Radio Checked <input id="use-check" type="checkbox" name="ifChecked" checked={this.state.ifChecked} value={this.state.ifChecked} onChange={this.handleChange} /> </label> </p> <p> // Display State Change in Component <h2>Show State Change</h2> <label> Changing State <input type="text" value={this.state.textValue} /> <input type="text" value={(this.state.ifChecked) ? "true" : "false"} /> </label> </p> </form> ); } } ReactDOM.render(<FormTable />, document.getElementById("root")); ``` # <span class="big-title">Lists & Keys</span> - This is used for multiple creation on element (such as `<li>`) - `Key` needs to be provided to every list - React diff algorithm use it to judge if it should manipulate on DOM - it wont be passed to `porps`, so if the information in key is useful, pass it by other attrs. ## <span class="intext-title">use `array.map` to generate `React List`</span> ```jsx= var numbers = [1, 2, 3] const listItem = numbers.map((x, index) => { <li key={index}>x</li> }); ReactDOM.render( <ul>{listItem}</ul>, document.getElementById("root") ); ``` # <span class="big-title">React Refs</span> - [Ref reference](https://zh-hant.reactjs.org/docs/refs-and-the-dom.html) - for Directly operation on DOM - for example, `focus()` DOM element - trigger real-time animation - ref cant be used on *function* component - it has no **instance** - It should be noticed that **reference is the invasion of encapsulation** - carefully use ! ## <span class="intext-title">Operation</span> - create reference via `React.createRef()` - bind created reference with attr `ref` - when that instance be mouneted (rendered), it's able to use `current` to access DOM element directly. ## <span class="intext-title">Example</span> ```jsx= class ReferenceTextInput extends React.Component{ constructor(props){ super(props); // Create Ref this.textRef = React.createRef(); // Bind event listener this.focusTextInput = this.focusTextInput.bind(this); } // Focus on ref focusTextInput(){ this.textRef.current.focus(); } // Trigger focus after mounting componentDidMount(){ this.focusTextInput(); } render(){ return ReactDOM.createPortal(( <React.Fragment> <h2>This is reference test</h2> // Bind Reference <input type="text" ref={this.textRef} /> </React.Fragment> ),document.getElementById("contain-text-input") ); } } ``` > when `ReferenceTextInput` been mounted to screen, text input of it will be focused. # <span class="big-title">Reference</span> - [W3C](https://www.w3schools.com/react/default.asp) - [React tutorial](https://zh-hant.reactjs.org/docs/hello-world.html) - [Fooish](https://www.fooish.com/) - [Tania Rascia](https://www.taniarascia.com/getting-started-with-react/) ## <span class="intext-title">快速 Review 一下</span> - React 是一個前端 Library, 在MVC 模型當中負責了 View 的部分。 - 可以搭配其他framework 做使用。 - 注意,並不建議與jQuery 等邏輯管理框架做混用。 - 在建立HTML 網頁結構時,通常透過#root (名稱並非固定)將部分區塊的渲染 (render) 交給React ,React 所採用的VDOM (Virtual DOM) 渲染方式避免了透過 JS 直接操作DOM 所造成的資源浪費。 - 在React 當中,透過組件(Component) 的方式管理部件的呈現,state 和props 的傳遞形成的單向資料流是render 的重要行為方針,其所使用的方式迥異於一般的繼承化管理。 - 使用JSX (將透過Babel 編譯成JS statement),可以將輸出的元素以接近HTML 的方式作呈現 - 可以直接寫HTML tag ! - 這也是某些人不愛用React 的原因 ! -> 不同語言的混用 vs 網頁的分離架構 - 在React 當中,某些HTML 元素會擁有不同的表現形式 - 本質上,這些HTML 仍為JS expression 他們可以說只是"長得很像HTML" 而已