其他分享
首页 > 其他分享> > React 入门

React 入门

作者:互联网

React 背景知识

React 是一个用于构建用户界面的 JavaScript 库,主要用于构建 UI,而不是一个 MVC 框架,但可以使用 React 作为 MVC 架构的 View 层轻易的在已有项目中使用,它是一个用于构建用户界面的 JavaScript 库,起源于 Facebook 的内部项目,用来架设 Instagram 的网站,于 2013 年 5 月开源。

React 特点

环境准备

方式一:在浏览器中编写代码

方法二:直接使用 Staticfile CDNReact CDN

<script src="https://cdn.staticfile.org/react/16.4.0/umd/react.development.js"></script>
<script src="https://cdn.staticfile.org/react-dom/16.4.0/umd/react-dom.development.js"></script>
<!-- 生产环境中不建议使用 -->
<script src="https://cdn.staticfile.org/babel-standalone/6.26.0/babel.min.js"></script>
<script src="https://unpkg.com/react@16/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>
<!-- 生产环境中不建议使用 -->
<script src="https://unpkg.com/babel-standalone@6.15.0/babel.min.js"></script>
<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8" />
    <title>Hello React!</title>
    <script src="https://cdn.staticfile.org/react/16.4.0/umd/react.development.js"></script>
    <script src="https://cdn.staticfile.org/react-dom/16.4.0/umd/react-dom.development.js"></script>
    <script src="https://cdn.staticfile.org/babel-standalone/6.26.0/babel.min.js"></script>
</head>
<body>

<div id="example"></div>
<script type="text/babel">
	ReactDOM.render(
		<h1>Hello, world!</h1>,
		document.getElementById('example')
	);
</script>

</body>
</html>

方式三:搭建本地开发环境,通过 npm 使用 React

在浏览器中打开 http://localhost:3000/ 就能看到运行结果。

my-app/
  README.md
  node_modules/
  package.json
  .gitignore
  public/
    favicon.ico
    index.html
    manifest.json
  src/
    App.css
    App.js
    App.test.js
    index.css
    index.js
    logo.svg

manifest.json 指定了开始页面 index.html,一切的开始都从这里开始,所以这个是代码执行的源头。

React 元素渲染

将元素渲染到 DOM 中

首先我们在一个 HTML 页面中添加一个 id=“example” 的

,如下:

<div id="example"></div>

React 开发应用时一般只会定义一个根节点。

要将React元素渲染到根DOM节点中,我们通过把它们都传递给 ReactDOM.render() 的方法来将其渲染到页面上:

const element = <h1>Hello, world!</h1>;
ReactDOM.render(
    element,
    document.getElementById('example')
);

更新元素渲染

React 元素都是不可变的。当元素被创建之后,你是无法改变其内容或属性的。

目前更新界面的唯一办法是创建一个新的元素,然后将它传入 ReactDOM.render() 方法,比如下面这个定时器:

function tick() {
  const element = (
    <div>
      <h1>Hello, world!</h1>
      <h2>现在是 {new Date().toLocaleTimeString()}.</h2>
    </div>
  );
  ReactDOM.render(
    element,
    document.getElementById('example')
  );
}
 
setInterval(tick, 1000);

ReactDOM.render调用函数及参数传递

 ReactDOM.render(
      < functionname  property1 = {property1_value}  property2 = {property2_value} />,
       document.getElementById('example')
   );

以下实例用一个函数来表示前面的定时器封装:

function Clock(props){
    return (
        <div id={props.id}>
            <h1>Hello, {props.name} ~</h1>
            <h2>现在是北京时间 {props.date.toLocaleTimeString()}</h2>
        </div>
    )
}

function tick() {
    ReactDOM.render(
        < Clock date={new Date()} name={'world'} id={'world'}/>,
        document.getElementById('example')
    );
}

setInterval(tick, 1000);

值得注意的是 React DOM 首先会比较元素内容先后的不同,而在渲染过程中只会更新改变了的部分。

创建React.Component 的 ES6 类

需要注意的是在 render() 方法中,需要使用this.props 替换 props,示例:

class Clock extends React.Component{
    render(){
        return(
            <div id={this.props.id}>
                <h1>Hello, {this.props.name} ~</h1>
                <h2>现在是北京时间 {this.props.date.toLocaleTimeString()}</h2>
            </div>
        )
    }
}

function tick() {
    ReactDOM.render(
        < Clock date={new Date()} name='world' id='world'/>,
        {/* new Date() 这样的value,需要使用花括号来包含,仅字符串的值则不需要 */}
        document.getElementById('example')
    );
}

setInterval(tick, 1000);

React JSX

js和jsx的区别

既然这里提到了jsx,那就顺便了解一下两者的区别:

使用 jsx

React 实例

ReactDOM.render(
    <div>
	    <h1>React JSX</h1>
	    <h2>欢迎学习 React jsx</h2>
	    <p data-myattribute = "somevalue">这是一个很不错的 JavaScript 库!</p>
    </div>,
    document.getElementById('example')
);

jsx独立文件

ReactDOM.render(
	<h1>hello, world</h1>,
	document.getElementById('example')
)
<body>
  	<div id="example"></div>
	<script type="text/babel" src="helloworld_react.js"></script>
</body>

JavaScript 表达式

ReactDOM.render(
    <div>
      <h1>{1+1}</h1>
    </div>
    ,
    document.getElementById('example')
);
ReactDOM.render(
 	<div>
      <h1>{i == 1 ? 'True!' : 'False'}</h1>
    </div>
    ,
    document.getElementById('example')
)

样式

React 推荐使用内联样式。我们可以使用 camelCase 小驼峰 语法来设置内联样式. React 会在指定元素数字后自动添加 px ,如font-size要写成fontSize:

let myStyle = {
	fontSize: 100,
	color: '#FF0000'
};
ReactDOM.render(
	<h1 style={myStyle}>hello, world {1+1}</h1>,
	document.getElementById('example')
)

注释

注释需要 写在花括号{} 中,实例如下:

ReactDOM.render(
	<h1>
		hello, world {1+1}
		{/*这是注释部分*/}
	</h1>,
	document.getElementById('example')
)

数组

JSX 允许在模板中插入数组,数组会自动展开所有成员:

let arr = [
	<h1>React教程</h1>,
	<h2>学的不仅是React,学的是方法。</h2>,
];
ReactDOM.render(
	<div>{arr}</div>,
	document.getElementById('example')
)

React 组件

实例解析:

function HelloMessage(props) {
	return <h1 className={props.class}>Hello {props.name}!</h1>;
}

const element = <HelloMessage class='testClass' name="Runoob"/>;

ReactDOM.render(
	element,
	document.getElementById('example')
);

注意:

复合组件

直接看例子吧:

function Name(props){
	return <h1>网站名称:{props.name}</h1>
}

function Url(props){
	return <h1>网站地址:{props.url}</h1>
}

function Nickname(props){
	return <h1>网站小名:{props.nickname}</h1>
}

function App(){
	return (
		<div>
			<Name name='React 复合组件学习'/>
			<Url url='http://www.runoob.com'/>
			<Nickname nickname={'React'}/>
		</div>
	)
}

ReactDOM.render(
	<App/>,
	document.getElementById('example')
);

React State(状态)

React 把组件看成是一个状态机(State Machines)。通过与用户的交互,实现不同状态,然后渲染 UI,让用户界面和数据保持一致。
React 里,只需更新组件的 state,然后根据新的 state 重新渲染用户界面(不要操作 DOM)。

将生命周期方法添加到类中

在具有许多组件的应用程序中,在销毁时释放组件所占用的资源非常重要。

我们可以在组件类上声明特殊的方法,当组件挂载或卸载时,来运行一些代码:


class Clock extends React.Component {
	constructor(props) {
		super(props)
		this.state = {date: new Date()}
	}

	componentDidMount(){
		let _this = this;
		this.timerID = setInterval(function (){
			_this.tick()
		}, 1000)
	}

	componentWillUnmount() {
		clearInterval(this.timerID)
	}

	tick(){
		this.setState({
			date: new Date()
		})
	}

	render(){
		return(
			<div>
				<h1>Hello, world!</h1>
				<h2>现在是北京时间:{this.state.date.toLocaleTimeString()}</h2>
			</div>
		)
	}
}

ReactDOM.render(
	<Clock />,
	document.getElementById('example')
);

实例解析:

数据自顶向下流动

父组件或子组件都不能知道某个组件是有状态还是无状态,并且它们不应该关心某组件是被定义为一个函数还是一个类。
这就是为什么状态通常被称为局部或封装。 除了拥有并设置它的组件外,其它组件不可访问。
以下实例中 FormattedDate 组件将在其属性中接收到 date 值,并且不知道它是来自 Clock 状态、还是来自 Clock 的属性、亦或手工输入

function FormattedDate(props){
	return <h2>现在是北京时间:{props.date.toLocaleTimeString()}</h2>
}

class Clock extends React.Component {
	constructor(props) {
		super(props)
		this.state = {date: new Date()}
	}

	componentDidMount(){
		let _this = this;
		this.timerID = setInterval(function (){
			_this.tick()
		}, 1000)
	}

	componentWillUnmount() {
		clearInterval(this.timerID)
	}

	tick(){
		this.setState({
			date: new Date()
		})
	}

	render(){
		return(
			<div>
				<h1>Hello, world!</h1>
				<FormattedDate date={this.state.date}/>
			</div>
		)
	}
}

function App(){
	return(
		<div>
			<Clock />
			<Clock />
			<Clock />
		</div>
	)
}

ReactDOM.render(
	<App />,
	document.getElementById('example')
);

这里我还没有完全理解它的含义!

React Props

stateprops 主要的区别在于 props 是不可变的,而 state 可以根据与用户交互来改变。

基本用法

前面的示例中都已经涉及到Props的使用,这里不再举例,只再提示一点普通类和ES6 class使用上的差别:

State 和 Props

例:在父组件中设置 state, 并通过在子组件上使用 props 将其传递到子组件上。在 render 函数中, 我们设置 name 和 site 来获取父组件传递过来的数据

class Book extends React.Component{
	constructor(props) {
		super(props)

		this.state = {
			name: 'react',
			time: '2013年5月',
		}
	}

	render() {
		return (
			<div>
				<Name name={this.state.name}/>
				<Time time={this.state.time}/>
			</div>
		)
	}
}

class Name extends React.Component {
	render(){
		return(
			<h1>Book name: {this.props.name}</h1>
		)
	}
}

class Time extends React.Component {
	render(){
		return(
			<h1>Book create time: {this.props.time}</h1>
		)
	}
}

ReactDOM.render(
	<Book />,
	document.getElementById('example')
)

Props 验证

React.PropTypes 在 React v15.5 版本后已经移到了 prop-types 库。 React v15.5 版本以上使用时需要引入:<script src="https://cdn.staticfile.org/prop-types/15.6.1/prop-types.js"></script>

Props 验证使用 propTypes,它可以保证我们的应用组件被正确使用,React.PropTypes 提供很多验证器 (validator) 来验证传入数据是否有效。当向 props 传入无效数据时,JavaScript 控制台会抛出警告。

React 16.4 实例:

var title = "react learner";
class MyTitle extends React.Component {
	render() {
		return (
			<h1>Hello, {this.props.title}</h1>
		);
	}
}

MyTitle.propTypes = {
	title: PropTypes.string
};
ReactDOM.render(
	<MyTitle title={title} />,
	document.getElementById('example')
);

更多验证器说明如下

MyComponent.propTypes = {
    // 可以声明 prop 为指定的 JS 基本数据类型,默认情况,这些数据是可选的
   optionalArray: React.PropTypes.array,
    optionalBool: React.PropTypes.bool,
    optionalFunc: React.PropTypes.func,
    optionalNumber: React.PropTypes.number,
    optionalObject: React.PropTypes.object,
    optionalString: React.PropTypes.string,
 
    // 可以被渲染的对象 numbers, strings, elements 或 array
    optionalNode: React.PropTypes.node,
 
    //  React 元素
    optionalElement: React.PropTypes.element,
 
    // 用 JS 的 instanceof 操作符声明 prop 为类的实例。
    optionalMessage: React.PropTypes.instanceOf(Message),
 
    // 用 enum 来限制 prop 只接受指定的值。
    optionalEnum: React.PropTypes.oneOf(['News', 'Photos']),
 
    // 可以是多个对象类型中的一个
    optionalUnion: React.PropTypes.oneOfType([
      React.PropTypes.string,
      React.PropTypes.number,
      React.PropTypes.instanceOf(Message)
    ]),
 
    // 指定类型组成的数组
    optionalArrayOf: React.PropTypes.arrayOf(React.PropTypes.number),
 
    // 指定类型的属性构成的对象
    optionalObjectOf: React.PropTypes.objectOf(React.PropTypes.number),
 
    // 特定 shape 参数的对象
    optionalObjectWithShape: React.PropTypes.shape({
      color: React.PropTypes.string,
      fontSize: React.PropTypes.number
    }),
 
    // 任意类型加上 `isRequired` 来使 prop 不可空。
    requiredFunc: React.PropTypes.func.isRequired,
 
    // 不可空的任意类型
    requiredAny: React.PropTypes.any.isRequired,
 
    // 自定义验证器。如果验证失败需要返回一个 Error 对象。不要直接使用 `console.warn` 或抛异常,因为这样 `oneOfType` 会失效。
    customProp: function(props, propName, componentName) {
      if (!/matchme/.test(props[propName])) {
        return new Error('Validation failed!');
      }
    }
  }
}

React 事件处理

向事件处理程序传递参数

通常我们会为事件处理程序传递额外的参数。例如,若是 id 是你要删除那一行的 id,以下两种方式都可以向事件处理程序传递参数:

<button onClick={(e) => this.deleteRow(id, e)}>Delete Row</button>
<button onClick={this.deleteRow.bind(this, id)}>Delete Row</button>

通过 bind 方式向监听函数传参,在类组件中定义的监听函数,事件对象 e 要排在所传递参数的后面,例如:

class Popper extends React.Component{
    constructor(){
        super();
        this.state = {name:'Hello world!'};
    }
    
    preventPop(name, e){    //事件对象e要放在最后
        e.preventDefault();
        alert(name);
    }
    
    render(){
        return (
            <div>
                <p>hello</p>
                {/* 通过 bind() 方法传递参数。 */}
                <a href="https://reactjs.org" onClick={this.preventPop.bind(this,this.state.name)}>Click</a>
            </div>
        );
    }
}

【未完待续】

参考

标签:入门,render,React,PropTypes,props,组件,ReactDOM
来源: https://blog.csdn.net/qq_37116222/article/details/118083113