react基础总结
具体详见官网:https://reactjs.org/docs/introducing-jsx.html
一、简介
用于构建用户界面的JavaScript库
1.react不是完整的MVC MVVM框架
二、安装
1.创建新应用(使用create-react-app)
npm install -g create-react-app
create-react-app my-app //创建一个名为my-app的react应用
cd my-app
npm start
注意:Create React App 并不处理后端逻辑和数据库,它只会创建一个前端的构建管道,所以可以和任何后端搭配使用
平常练习可用codepan 进行练习
三、概要
1.JSX - javascript的一种扩展语法
作用:你可以将 javscript表达式 和 html代码 结合在一起呈现。这样的想法实际与angular逻辑与表现相分离。
方法:用 花括号({ })把任意的 JavaScript 表达式 嵌入到 JSX 中。
1)JSX嵌入表达式
function formatName(user) {
return user.firstName + ' ' + user.lastName +' '+ user.message;
}
const user = {
firstName: 'Harper',
lastName: 'Perez',
message: 'good job'
};
const element = (
<h1>
Hello, {formatName(user)}!
</h1>
);
ReactDOM.render(
element,
document.getElementById('root')
);
2)JSX也是一个表达式
可以在 i f 语句,for语句,return语句
3)用 JSX 指定属性值
2.元素渲染(render)
方法:ReactDOM.render( 组件/html标签 , Dom节点 )
进行元素渲染(更新UI),每次state状态中属性值发生变化,都会重新渲染render()方法
return - 渲染一个单节点元素
3.Components 和 Props
3.1 组件 - 形成独立的,可以重复使用的部分
组件定义方式:函数定义/类定义 组件
①函数定义
function Welcome(props){
return <h1>hello,{props.name}</h1>
}
将函数转化为类
1)创建一个名称扩展为React.Component 的Es6类
2) 创建一个render(){} 的空方法
3)将函数体移动到render 方法中
4)在render(){} 中用 this.props 代替 props
②es6类定义 - React.Component
class Welcame extends React.Component{
render(){
return <h1>hello,{this.props.name}</h1>
}
}
3.2 props
回顾一下:
React元素可以是用DOM标签const element = <h1> hello </h1>
,也可以是我们自定义的组件const element = <Welcome name="JSX"/>
当React遇到的元素是用户自定义的组件,它会将JSX属性作为单个对象传递给该组件,这个对象称之为“props”。
props特点:props作为传入组件内部的对像,具有只读性
1)组件间属性的传递,就要想到props属性
①:传递值
class Welcome extends COmponent{
render(){
return (
<div>{this.props.name}</div>
);
}
}
.....
`const element = <Welcome name="JSX"/>`
②:传递方法
class LoginControl extends React.Component {
constructor(props) {
super(props);
this.state = {
isLogin: false
};
}
handelSignin() {
console.log(this.state.isLogin);
}
render() {
const isLogin = this.state.isLogin;
return (
<div>
.......
必须绑定this;因为class类中,方法并没有绑定this
<Signin onClick={this.handelSignin.bind(this)} />
......
</div>
);
}
}
class Signout extends React.Component {
render() {
return <button onClick={() => this.props.onClick()}>signout</button>;
}
}
4.state和lifecycles
4.1 state
state 就相当于在一个类中添加了局部状态
①从组件中的属性变成状态 render()方法中 this.state....
替换 this.props...
②在类中添加一个constuctor()方法来初始化state
constructor(props) {
super(props); //
this.state = {date: new Date()};
}
调用super的原因:在ES6中,在子类的constructor中必须先调用super才能引用this
super(props)的目的:在constructor中可以使用this.props
super(props)的目的:在constructor中可以使用this.props
注意我们如何传递 props 到基础构造函数的:
//完整例子
class Welcame extends React.Component{
constructor(props){
super(props);
this.state = {name : 'JSX'};
}
render(){
return <h1>hello,{this.state.name}</h1>
}
}
ReactDOM.render(
<Welcame />,
document.getElementById('root')
);
更新状态的方法是才用this.setState({
});
4.2 将lifeCycles 添加到类中
—– componentDidMount() { } 、componentWillUnmount() {},这些方法被称为生命周期钩子
在具有许多组件的应用程序中,在销毁时释放组件所占用的资源非常重要。所以生命周期钩子就在这时具有重要作用。(详细详见 - react -medium knoeledge)
5.事件处理
React事件处理与DOM事件处理的区别
1)事件绑定属性的命名采用驼峰式写法,而不是小写。
2)如果采用 JSX 的语法你需要传入一个函数作为事件处理函数,而不是一个字符串(DOM元素的写法)
<button onclick="activateLasers()">
Activate Lasers
</button>
html写法:绑定属性小写,传入字符串
<button onClick={activateLasers}>
Activate Lasers
</button>
react写法:绑定属性驼峰,传入函数
通过类定义方法时,要注意this 事件的绑定
class Toggle extends React.Component {
constructor(props) {
super(props);
this.state = {isToggleOn: true};
// This binding is necessary to make `this` work in the callback
this.handleClick = this.handleClick.bind(this);
}
handleClick() {
this.setState(prevState => ({
isToggleOn: !prevState.isToggleOn
}));
}
render() {
return (
<button onClick={this.handleClick}>
{this.state.isToggleOn ? 'ON' : 'OFF'}
</button>
);
}
}
ReactDOM.render(
<Toggle />,
document.getElementById('root')
);
6.条件渲染
React 中的条件渲染和 JavaScript 中的一致,使用 JavaScript 操作符 if 或条件运算符来创建表示当前状态的元素,然后让 React 根据它们来更新 UI。
1)if 操作符
//根据isLoggedIn的值渲染不同的结果
function UserGreeting(props) {
return <h1>Welcome back!</h1>;
}
function GuestGreeting(props) {
return <h1>Please sign up.</h1>;
}
function Greeting(props) {
const isLoggedIn = props.isLoggedIn;
if (isLoggedIn) {
return <UserGreeting />;
}
return <GuestGreeting />;
}
ReactDOM.render(
// Try changing to isLoggedIn={true}:
<Greeting isLoggedIn={true} />,
document.getElementById('root')
);
2)三目运算 ?: (可直接在return语句使用)
//登录登出案例
import React from "react";
import { render } from "react-dom";
//full component
class LoginControl extends React.Component {
constructor(props) {
super(props);
this.state = {
isLogin: false
};
}
handelSignin() {
this.setState({
isLogin: true
});
}
handelSignout() {
this.setState({
isLogin: false
});
}
render() {
const isLogin = this.state.isLogin;
return (
<div>
<Greeting isLogin={isLogin} />
{isLogin ? (
<Signout onClick={this.handelSignout.bind(this)} />
) : (
<Signin onClick={this.handelSignin.bind(this)} />
)}
</div>
);
}
}
//Greeting Component
class Greeting extends React.Component {
render() {
const isLogin = this.props.isLogin;
if (isLogin) {
return <div>please sign out</div>;
} else {
return <div>please sign in</div>;
}
}
}
//Signin Button
function Signin(props) {
return <button onClick={props.onClick}>Login</button>;
}
//Signout Button
class Signout extends React.Component {
constructor(props) {
super(props);
}
render() {
return <button onClick={this.props.onClick}>signout</button>;
}
}
render(<LoginControl />, document.getElementById("root"));
3)&&运算符
function Mailbox(props) {
const unreadMessages = props.unreadMessages;
return (
<div>
<h1>Hello!</h1>
{unreadMessages.length > 0 &&
<h2>
You have {unreadMessages.length} unread messages.
</h2>
}
</div>
);
}
const messages = ['React', 'Re: React', 'Re:Re: React'];
ReactDOM.render(
<Mailbox unreadMessages={messages} />,
document.getElementById('root')
);
7.list(列表)和keys
React中渲染多个组建与JS方法类似,使用JSX
function ListItem(props) {
// 对啦!这里不需要指定key:
return <li>{props.value}</li>;
}
function NumberList(props) {
const numbers = props.numbers;
const listItems = numbers.map((number,index) =>
// 又对啦!key应该在数组的上下文中被指定
<ListItem key={number.toString()}
value={number} />
);
return (
<ul>
{listItems}
</ul>
);
}
const numbers = [1, 2, 3, 4, 5];
ReactDOM.render(
<NumberList numbers={numbers} />,
document.getElementById('root')
);
8.表单
React 中表单元素不能与其他标签元素在 html 一致,因为表单元素是有一些内部状态的。(受控组件)
受控组件:input select textarea
在HTML当中,像<input>,<textarea>,<select>
这类表单元素会维持自身状态,并根据用户输入进行更新。但在React中,可变的状态通常保存在组件的状态属性中(state),并且只能用 setState().
方法进行更新.
在react中,<input type="text">, <textarea>
, 和 <select>
都十分类似 - 他们都通过传入一个value属性来实现对组件的控制。
注意:当有多手控的的input元素时,例如<input type="text">
,<input type="checkbox">
,<input type="number">
,我们可以给每个元素添加name属性,来让处理函数根据event.target.name
来确定改变哪一个input 元素
class Reservation extends React.Component {
constructor(props) {
super(props);
this.state = {
isGoing: true,
numberOfGuests: 2
};
this.handleInputChange = this.handleInputChange.bind(this);
}
handleInputChange(event) {
const target = event.target;
const value = target.type === 'checkbox' ? target.checked : target.value;
const name = target.name;
this.setState({
[name]: value
});
}
render() {
return (
<form>
<label>
Is going:
<input
name="isGoing"
type="checkbox"
checked={this.state.isGoing}
onChange={this.handleInputChange} />
</label>
<br />
<label>
Number of guests:
<input
name="numberOfGuests"
type="number"
value={this.state.numberOfGuests}
onChange={this.handleInputChange} />
</label>
</form>
);
}
}
ReactDOM.render(
<Reservation />,
document.getElementById('root')
);
7.组合和继承