React.js快速入门小册

全局API

创建React组件

  • 组件中必须(也有非必须的方案)有且只有一个根节点
1.函数式创建
  • app.jsx
import React from 'react'
function App(props){
return (<div>我是app</div>)
}
复制代码

纯函数式创建的组件无声明周期,无state。适合无状态的组件使用。官方推荐。如果想使用状态,React在16.8增建了HOOKS

2.ES6类式创建
  • app.jsx
import React from 'react'
class App extends React.component(){
constructor(props){
super(props)
this.state={

}
}
// 相关生命周期函数用不到的话可以省略
// ...

// 类式申明的组件必须要用render函数
render(){
return (<div></div>)
}
}
复制代码
3.采用React class创建
  • app.jsx
var Hello = React.creatClass({
getDefaultProps: function(){
return {
name: 'pomy',
git: 'dwqs'
}
},
render: function(){
return (
<div>Hello,{this.props.name},git username is {this.props.dwqs}</div>
)
}
});
复制代码

生命周期

参考文档:React生命周期

getDefaultProps

对于每个组件实例来讲,这个方法只会调用一次,该组件类的所有后续应用,getDefaultPops 将不会再被调用,其返回的对象可以用于设置默认的 props(properties的缩写) 值。

注:返回的对象为this组件实例下的props

getInitialState

对于组件的每个实例来说,这个方法的调用有且只有一次,用来初始化每个实例的 state,在这个方法里,可以访问组件的 props。每一个React组件都有自己的 state,其与 props 的区别在于 state只存在组件的内部,props 在所有实例中共享

class App extends React.component(){
getInitialState() {
return {liked: false};
},
handleClick(event) {
this.setState({liked: !this.state.liked});
},
render() {
}
}
复制代码

访问的时候通过this.state访问

componentWillMount

该方法在首次渲染之前调用,也是再 render 方法调用之前修改 state 的最后一次机会。

componentDidMount

已经渲染出来了真实的DOM,这个时候可以访问DOM元素了。一般在此周期下进行服务端数据的请求

class App extends React.component(){
componentDidMount(){
console.log(this.getDOMNode())
}
render(){
return <div></div>
},
}
复制代码
componentWillReceiveProps

组件的 props 属性可以通过父组件来更改,这时,componentWillReceiveProps 将来被调用。可以在这个方法里更新 state,以触发 render 方法重新渲染组件。


class App extends React.component(){
componentWillReceiveProps(nextProps){
if(nextProps.checked !== undefined){
this.setState({
checked: nextProps.checked
})
}
}
render(){
return <div></div>
},
}
复制代码
shouldComponentUpdate

如果你确定组件的 props 或者 state 的改变不需要重新渲染,可以通过在这个方法里通过返回 false 来阻止组件的重新渲染,返回 `false 则不会执行 render 以及后面的 componentWillUpdate,componentDidUpdate 方法。

class App extends React.component(){
shouldComponentUpdate(){
return this.state.checked === nextState.checked;
//return false 则不更新组件
}
render(){
return <div></div>
},
}
复制代码
componentWillUpdate

这个方法和 componentWillMount 类似,在组件接收到了新的 props 或者 state 即将进行重新渲染前,componentWillUpdate(object nextProps, object nextState) 会被调用,注意不要在此方面里再去更新 props 或者 state

class App extends React.component(){
componentWillUpdate(){
}
render(){
return <div></div>
},
}
复制代码
componentDidUpdate

这个方法和 componentDidMount 类似,在组件重新被渲染之后,componentDidUpdate(object prevProps, object prevState) 会被调用。可以在这里访问并修改 DOM。

class App extends React.component(){
componentDidMount(){
}
render(){
return <div></div>
},
}
复制代码
componentWillUnmount

每当React使用完一个组件,这个组件必须从 DOM 中卸载后被销毁,此时 componentWillUnmout 会被执行,完成所有的清理和销毁工作,在 componentDidMount 中添加的任务都需要再该方法中撤销,如创建的定时器或事件监听器

class App extends React.component(){
componentWillUnmount(){
}
render(){
return <div></div>
},
}
复制代码
render

该方法会创建一个虚拟DOM,用来表示组件的输出。对于一个组件来讲,render方法是唯一一个必需的方法。render方法需要满足下面几点:

  • 只能通过 this.props 和 this.state 访问数据(不能修改)
  • 可以返回 null,false 或者任何React组件
  • 只能出现一个顶级组件,不能返回一组元素
  • 不能改变组件的状态
  • 不能修改DOM的输出 render方法返回的结果并不是真正的DOM元素,而是一个虚拟的表现,类似于一个DOM tree的结构的对象。react之所以效率高,就是这个原因。

state的使用

react将状态存到state中,通过setState改变state中的值。从而出发dom渲染

注:但是不要直接修改state,要通过 this.setState 方法来修改。

// 利用函数设置
this.setState((prevState, props) => ({
counter: prevState.counter + props.increment
}));
复制代码

或者

// 直接使用,注意在更改comment值后在下面不能直接拿到comment的新值,要取值的话可以采用回调的方式
this.setState({comment: 'Hello'});

this.setState({comment:'hello'},(nextState)=>{console.log(nextState.comment)})
复制代码
getDerivedStateFromProps

组件之间的传参

父子组件传参采用props

状态管理器 Redux

路由参数

jsx语法相关

标签类型

在JSX语法中,使用的标签类型有两种:DOM类型的标签(div、span等)和React组件类型的标签(关注后面文章)。DOM类型的标签需要标签的首字母小写,React组件类型的标签需要首字母大写。React也是通过首字母的大小写来判断渲染的是哪种类型的标签。

JSX语法

在{}中写入相关代码,jsx不支持if else ,支持三元运算符。

JSX添加style
<script type="text/babel">
var ok=1;
ReactDOM.render(
<div>
<p style={{
color:"red",
fontSize:50
}}>{ok==1?"我很帅":"我很有才华"}</p>
</div>,
document.querySelector("#wrap")
)
</script>
复制代码
JSX属性名
  1. 所有的属性都是驼峰命名的;
  2. class 属性 改为 className;
  3. for 属性 改为 htmlFor;
  4. colspan 属性 改为 colSpan
事件

onCLickonMouseOver

Redux

react-router

React.render((
<Router>
<Route path="/" component={App}>
<Route path="about" component={About} />
{/* 当 url 为/时渲染 Dshboard */}
<IndexRoute component={Dashboard} />
<Route path="inbox" component={Inbox}>
<Route path="messages/:id" component={Message} />
</Route>
</Route>
</Router>
), document.body)
复制代码

PropTypes 验证器

import React from 'react';
import PropTypes from 'prop-types';

class MyComponent extends React.Component {
render() {
// 利用属性做更多得事
}
}

MyComponent.propTypes = {
//你可以定义一个属性是特定的JS类型(Array,Boolean,Function,Number,Object,String,Symbol)。默认情况下,这些都是可选的。

optionalArray: PropTypes.array,
optionalBool: PropTypes.bool,
optionalFunc: PropTypes.func,
optionalNumber: PropTypes.number,
optionalObject: PropTypes.object,
optionalString: PropTypes.string,
optionalSymbol: PropTypes.symbol,

//指定类型为:任何可以被渲染的元素,包括数字,字符串,react 元素,数组,fragment。
optionalNode: PropTypes.node,

// 指定类型为:一个react 元素
optionalElement: PropTypes.element,

//你可以类型为某个类的实例,这里使用JS的instanceOf操作符实现
optionalMessage: PropTypes.instanceOf(Message),


//指定枚举类型:你可以把属性限制在某些特定值之内
optionalEnum: PropTypes.oneOf(['News', 'Photos']),

// 指定多个类型:你也可以把属性类型限制在某些指定的类型范围内
optionalUnion: PropTypes.oneOfType([
PropTypes.string,
PropTypes.number,
PropTypes.instanceOf(Message)
]),

// 指定某个类型的数组
optionalArrayOf: PropTypes.arrayOf(PropTypes.number),

// 指定类型为对象,且对象属性值是特定的类型
optionalObjectOf: PropTypes.objectOf(PropTypes.number),


//指定类型为对象,且可以规定哪些属性必须有,哪些属性可以没有
optionalObjectWithShape: PropTypes.shape({
optionalProperty: PropTypes.string,
requiredProperty: PropTypes.number.isRequired
}),

// 指定类型为对象,且可以指定对象的哪些属性必须有,哪些属性可以没有。如果出现没有定义的属性,会出现警告。
//下面的代码optionalObjectWithStrictShape的属性值为对象,但是对象的属性最多有两个,optionalProperty 和 requiredProperty。
//出现第三个属性,控制台出现警告。
optionalObjectWithStrictShape: PropTypes.exact({
optionalProperty: PropTypes.string,
requiredProperty: PropTypes.number.isRequired
}),

//加上isReqired限制,可以指定某个属性必须提供,如果没有出现警告。
requiredFunc: PropTypes.func.isRequired,
requiredAny: PropTypes.any.isRequired,

// 你也可以指定一个自定义的验证器。如果验证不通过,它应该返回Error对象,而不是`console.warn `或抛出错误。`oneOfType`中不起作用。
customProp: function(props, propName, componentName) {
if (!/matchme/.test(props[propName])) {
return new Error(
'Invalid prop `' + propName + '` supplied to' +
' `' + componentName + '`. Validation failed.'
);
}
},

//你也可以提供一个自定义的验证器 arrayOf和objectOf。如果验证失败,它应该返回一个Error对象。
//验证器用来验证数组或对象的每个值。验证器的前两个参数是数组或对象本身,还有对应的key。
customArrayProp: PropTypes.arrayOf(function(propValue, key, componentName, location, propFullName) {
if (!/matchme/.test(propValue[key])) {
return new Error(
'Invalid prop `' + propFullName + '` supplied to' +
' `' + componentName + '`. Validation failed.'
);
}
})
复制代码

Fragments

对于一个组件中需要返回多个并列的节点的

class Columns extends React.Component {
render() {
return (
<React.Fragment>
<td>Hello</td>
<td>World</td>
</React.Fragment>
);
}
}
复制代码

或者

class Columns extends React.Component {
render() {
return (
<>
<td>Hello</td>
<td>World</td>
</>
);
}
}
复制代码

Refs

class MyComponent extends React.Component {
constructor(props) {
super(props);
this.myRef = React.createRef();
}
// 访问
const node = this.myRef.current;
render() {
return <div ref={this.myRef} />;
}
}
复制代码

或者采用回调的方式

function CustomTextInput(props) {
// 这里必须声明 textInput,这样 ref 回调才可以引用它
let textInput = null;

function handleClick() {
textInput.focus();
}
return (
<div>
<input
type="text"
ref={(input) => { textInput = input; }} />

<input
type="button"
value="Focus the text input"
onClick={handleClick}
/>
</div>
);
}

复制代码

Context

可以用于跨父子组件传参

新的用法
1.创建一个context
  • theme-context.js
export const themes = {
light: {
foreground: '#ffffff',
background: '#222222',
},
dark: {
foreground: '#000000',
background: '#eeeeee',
},
};

export const ThemeContext = React.createContext(
themes.dark // 默认值
);

复制代码
2.祖先组件
  • app.js
import {ThemeContext, themes} from './theme-context';
import ThemedButton from './themed-button';

// 一个使用到ThemedButton组件的中间组件
function Toolbar(props) {
return (
<ThemedButton onClick={props.changeTheme}>
Change Theme
</ThemedButton>
);
}

class App extends React.Component {
constructor(props) {
super(props);
this.state = {
theme: themes.light,
};

this.toggleTheme = () => {
this.setState(state => ({
theme:state.theme === themes.dark? themes.light: themes.dark,
}));
};
}

render() {
// ThemedButton 位于 ThemeProvider 内
// 在外部使用时使用来自 state 里面的 theme
// 默认 dark theme
return (
<Page>
<ThemeContext.Provider value={this.state.theme}>
<Toolbar changeTheme={this.toggleTheme} />
</ThemeContext.Provider>
<Section>
<ThemedButton />
</Section>
</Page>
);
}
}

ReactDOM.render(<App />, document.root);
复制代码
3.子组件
import {ThemeContext} from './theme-context';

function ThemedButton(props) {
return (
<ThemeContext.Consumer>
{theme => (
<button
{...props}
style={{backgroundColor: theme.background}}
/>

)}
</ThemeContext.Consumer>
);
}

export default ThemedButton;
复制代码
总结

祖先组件采用Provider包裹起来,子组件采用Consumers进行接收,每当Provider的值发生改变时, 作为Provider后代的所有Consumers都会重新渲染。 从Provider到其后代的Consumers传播不受shouldComponentUpdate方法的约束,因此即使祖先组件退出更新时,后代Consumer也会被更新。

之前的使用方式

1.在祖先组件中定义

  • Form.js

export default class Form extends Component {
constructor(props) {
super(props);
this.state = {
}
}

// 传值
getChildContext(){
return {
component: this
};
}

render(){
return ()
}
}

// 声明类型
Form.childContextTypes = {
component: PropTypes.any
};

复制代码

在子组件中

  • form-item.js
export default class FormItem extends Component {
constructor(props) {
super(props);
this.state = {
}
}
// 使用 this.context
parent(){
return this.context.component;
}
}
// 声明要就收的祖先组件的参数
FormItem.contextTypes = {
component: PropTypes.any
};

复制代码

转载于:https://juejin.im/post/5ce5f2caf265da1bb679efbc

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值