React 开发手册

基本概念

  • React是一个用于构建用户界面的Javascript库,是DOM的一个抽象层
  • React主要用于构建UI

状态管理

State

Props

路由

  • 主要使用的是React Router,包括react-routerreact-router-domreact-router-native
1
2
3
4
5
6
7
8
9
10
11
12
13
import { Switch, Route } from 'react-router-dom'

const Main = () => (
<main>
<Switch>
<Route path='/roster' component={Home}/>
<Route path='/schedule' component={Post}/>
<Route path='/about', render={() => <About something={this.something}>}/> <!--通过这种方式绑定数据或者方法给子路由-->
</Switch>
</main>
)

this.props.location.pathname; // 获取当前的url路径

组件

组件属性

  • 动态添加元素样式style

    1
    <div style={{display: this.state.show ? "block" : "none"}}>动态样式</div>
  • 动态添加类class

    1
    <div className={this.state.show ? "show-class" : "hide-class"}>动态类</div>

常用组件

Prompt

  • 在路由即将切换前弹出确认框(离开前确认)
  • 需要注意的是,如果用户点击了取消,那么会组织路由的切换,但是用户的点击事件如果有监听,依然会触发点击事件的
  • 最好在message里面判断是否需要展示Prompt,不要在when里面,因为在when里面,每次重新render都会执行,但是message里面只是在用户真的打算跳转的时候才会执行
1
2
3
<Prompt 
when={true}
message={(params) => params.pathname == '/当前路径' ? true : "确认离开" } /> // 当返回文字的时候会弹出确认,而返回true的时候则不会弹出

条件渲染

如果实在JSX外部的js部分代码,那么直接使用js自己的if或者其他条件判断即可完成。在JSX内部的话一般则是使用逻辑与&&或者三目运算符完成。例如

1
2
3
4
5
6
7
8
9
10
11
12
render() {
return (
<div>
{this.state.posts.length > 0 &&
<p>There is some posts</p>
}
</div>
<div>
<p>There is {this.state.posts !== undefined ? this.state.posts.length : 0} posts.</p>
</div>
)
}

必备三方组件

React-Redux

  • 从后端的角度看,就是一个维护全局变量的东西

  • Action定义了要发生什么,并且携带着数据,reducer用来定义发生该事情后需要做什么,selector可以理解是从state获取数据额API。

  • Redux可以通过connect方法,将storedispatch方法保存到组件的props
  • stateprops的对应通常需要使用mapStateToProps这个函数进行定义。它默认会订阅Store,每当state更新的时候,就会自动执行,重新计算UI组件的参数
  • 下面的方法在跟组件外面包了一层Provider,这样所有的子组件默认都能拿到store
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
import { Provider } from 'react-redux'
import { createStore } from 'redux'
import rerducer from './reducers'
import App from './App'

const store = createStore(
reducer
);

ReactDOM.render(
<Provider store={store}>
<App />
</Provider>,
document.getElementById("root")
);

React-Saga

  • 从后端的角度看,就是在启动应用的时候,再启动一些单独的线程,这些线程可以异步去做些更改变量或者监听的事情,类似于钩子。

  • 可以在这里对异步操作进行集中处理。

  • Effect的几种方法:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    import {take,call,put,select,fork,takeEvery,takeLatest} from 'redux-saga/effects'
    // take: 用来监听action,返回监听到的action对象,例如如果有一个type=login的action,那么在执行dispatch(loginAction)之后,就可以这样获取简体你到的对象
    const action = yield take('login')

    // call: 调用指定函数
    yield call(myfunc, param1, param2);

    // put: 和dispatch类似,用于发送action
    yidle put({type: 'login'})

    // select: 和getState类似,用于获取store中的state
    const state = yield select()

    // fork

    // takeEvery/takeLatest: 用于监听

简单的例子:

1
2
3
4
5
6
7
8
9
10
11
// 在编写saga的文件里面一般这样写钩子函数
export function * mySaga() {
console.log("Hello Saga");
}

// 在main.js中,这样引入saga中间件
import createSagaMiddleware from 'redux-saga';
import {helloSaga} from './saga.js';
const sageMiddleware = createSagaMiddleware();
const store = createStore(rerducer, aplyMiddleware(sagaMiddleware));
sagaMiddleware.run(helloSaga);

Styled-Components

  • 目的是将React组件包装成Styled组件
1
2
3
4
5
6
7
8
9
10
11
12
13
import { Card } from 'antd';

const StyledComponent = styled(Card)` // 可以接收一个React-Componetn例如Card,也可以接收一个tagName例如div
div {
color: red;
}
.abc {
color: blue;
width: ${props => props.width} // 变量传递
}
`
// 在render里面就可以直接使用该组件了
<StyledComponent width={"12px"}></StyledComponent>

事件

支持事件列表

1
2
3
// 焦点事件
onBlur
onFocus

TroubleShooting

  • React 表达式必须有一个父元素: 常出现在JSX的渲染的内嵌语句中返回了错误格式的结果:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    render() {
    return (
    {
    [ // 需要返回的应该是数组而不是混搭
    <p>abc</p>,
    <p>def</p>,
    ]
    })
    }
扩展阅读