标签:create 语法 NPU 标签 click 命名 UNC 构造函数 fragment
npx create-react-app appName
JSX是一种JS语法扩展,可以在JS中编写类似于HTML的语法。需要明确的是,JSX本质是语法糖,我们写的并非是真正的HTML。
有两种存在形式:函数组件 和 类组件。下面的例子中它们是等价的。
function App() { return ( <div> Hello World! </div> ); } class App extends React.Component { render() { return ( <div>Hello World!</div> ); } }
要明确的是:
那么,是不是说函数组件一无是处呢?那倒不是,当页面的某些部分不需要内部数据,或者其展示的数据由父组件提供,我们可以使用书写更简便的函数组件。
我们知道,每个组件中,最外层必须只有一个HTML标签或组件,比如这样:
// 正确 class App extends React.Component{ render() { return ( <div> Hello World </div> ); } } // 错误 class App extends React.Component{ render() { return ( <div>Hello World</div> <div>Hello World</div> ); } }
有的页面极其复杂,DOM元素套了一层又一层,有时候我们不想这个组件外面套一层无意义的DIV,这时需要用到占位符,有两种写法:
import React, {Fragment} from ‘react‘; class App extends React.Component { render() { return ( <Fragment> <div>Hello World</div> <div>Hello World</div> </Fragment> ); } } 或 class App extends React.Component { render() { return ( <> <div>Hello World</div> <div>Hello World</div> </> ); } }
这样,渲染出来的页面 DOM 就没有多余的嵌套元素了。
因为JSX语法是存在于JavaScript中的,很多HTML和CSS的属性写在其中,有可能和JS发生混淆,例如HTML标签属性class就会和JS中的class混淆。为了避免这种混乱,HTML中的属性改了一种写法。
<label htmlFor=‘insertArea‘>请输入内容</label> <input className=‘input‘ id=‘insertArea‘ value={ this.state.inputValue } onChange={ this.handInputData } ref={(content)=>{this.inputData = content}}/> {/* 在为元素添加样式类的时候,建议使用className,否则React会认为容易与js中的class关键字混淆 */} {/* 为label添加for属性的时候,建议使用htmlFor */} {/* 事件绑定,全部采用驼峰命名法 */}
通过ref属性获取
render() { return ( <Fragment> <button ref = {(el)=>{this.buttonDom = el}}>提交</button> </Fragment> ); }
通过this.buttonDom即可获取
class App extends Component { addHandler(){ console.log(this) } render() { return ( <Fragment> <button onClick={ this.addHandler.bind(this) }>提交</button> </Fragment> ); } }
如果没有bind(this),回调函数内的this并没有指向本组件。如果每个事件绑定都要bind(this),不仅代码冗余,且浪费性能。我们可以将bind(this)过程放在构造函数中,回调只需bind一次即可。
class App extends Component { constructor(props) { super(props); // 继承并执行父类中的构造器 this.state = { inputValue: "", list: [], }; this.addHandler = this.addHandler.bind(this); } addHandler(){ console.log(this) } render() { return ( <Fragment> <button onClick={ this.addHandler }>提交</button> </Fragment> ); } }
如果回调函数的定义使用箭头函数,则更简洁。
class App extends Component { addHandler = () => { console.log(this) } render() { return ( <Fragment> <button onClick={ this.addHandler }>提交</button> </Fragment> ); } }
React组件内部的数据要存放在state中,当state中的数据发生变化时,组件将发生更新。
修改state中的数据必须通过setState方法,其它的修改方式都是非法的。
class App extends React.Component { constructor(props) { super(props); this.state = { count: 0, value: "", }; } clickCount = () => { // this.setState({ // count: this.state.count + 1 // }) // console.log(this.state.count); // 由于setState是异步函数,这里输出的count可能是修改之前的数据。 // 如果想要在修改后获取最新的数据,可以使用回调函数的写法。第一个函数返回要修改的数据,当修改完成后执行第二个回调。 this.setState((prev) => ({ count: prev.count + 1 }), ()=>{ console.log(this.state); }) }; changeHandle = (e) => { this.setState({ value: e.target.value, }) }; render() { return ( <> <div>value { this.state.value }</div> <div>cunt { this.state.count }</div> <input onChange={ this.changeHandle }/> <button onClick={ this.clickCount }>修改count</button> </> ); } }
<span dangerouslySetInnerHTML={{__html:value}}></span>
父传子:
通过自定义属性传递。
class App extends React.Component { constructor(props) { super(props); this.state = { count: 0, value: "", }; } render() { return ( <> <Item content={this.state.value} /> </> ); } } class Item extends React.Component{ render() { return ( <div>{this.props.content}</div> ) } }
子传父:
子组件无法直接修改父组件中的数据,通过调用父组件的方法来达到目的。
首先将父组件的方法传入子组件,在子组件中调用此函数。
class App extends React.Component { constructor(props) { super(props); this.state = { count: 0, value: "", }; } render() { return ( <> <Item content={this.state.value} sign={this.changeCount} /> </> ); } } class Item extends React.Component{ clickHandle = () => { const { sign } = this.props; sign("hello"); }; render() { return ( <> <div>{this.props.content}</div> <button onClick={this.clickHandle}>改变父组件</button> </> ) } }
标签:create 语法 NPU 标签 click 命名 UNC 构造函数 fragment
原文地址:https://www.cnblogs.com/V587Chinese/p/11629742.html