一、setState函數
一個異步函數,接受第二個參數,是一個回調函數
不能直接修改state中的值,可以進行一次深拷貝
this.state.inputValue (大大的錯誤)
二、生命週期函數
1.進行props和state的初始化
2.mounting組件在頁面掛載中
componentWillMount 組件在被掛載之前
render 組件被渲染進行掛載
componentDidMount 組件掛載完成
3.updation組件被更新
componentWillReceiveProps該生命週期的執行需要接受到父組件傳過來的參數,並且是在組件已經存在於父組件中才會執行,第一次存在是不會執行的
shouldComponentUpdate 詢問組件是否可以更新,return true便讓其進行接下來的更新和生命週期函數;return false 則不行
componentWillUpdate 組件即將被更新
render組件渲染
componentDidUpdate組件更新完畢
4.unmounting
componentWillUnmounting 組件被頁面祛除之前執行
生命週期的使用場景:
1. render生命週期的執行是props和state更新時或者父組件render時,子組件render就會重新更新,這樣會導致一個問題,一旦父組件更新,子組件就更新,但是有的時候子組件是沒有必要的
shouldComponentUpdate:可以優化這個性能損耗
shouldComponentUpdate(nextProps,nextState){
if(nextProps.xxx !== this.props.xxx){
return true;
}else{
return false;
}
}
2.ajax請求發送,在componentDidMount中執行
yarn add axios
import axis from 'axios';
axios.get('xxx').then(()=>{
xxxx
}).catch(() => {
xxx
})
3.關於render什麼時候會執行
1)初始化
2)setState()在任何情況下都會導致組件的重新渲染,即使state未發生變化
3)父組件render則子組件就會render
三、redux
四、無狀態組件
當一個組件只有render函數的時候,比如UI組件,不做邏輯處理時,我們可以不吧它寫成一個類的形式, 可以寫成一個函數爆露出去
const ComponentUI = (props) => {
...
}
export default ComponentUI;
五、redux-thunk中間件
1.在github上搜索redux-thunk安裝並引入相應插件,本來action只能接受一個對象,然後傳遞給store,但是當我們需要傳遞一個函數,讓action變成一個函數的時候,函數處理後得到結果在傳遞給store的時候就可以利用中間件進行實現
2.如果想這個中間件和devtools一起使用,可以在github上搜索redux-devtools-extension查看高級的store配置
3.我的項目配置
import { createStore ,applyMiddleware ,compose} from 'redux'
import thunk from 'redux-thunk';
import reducer from './reducer.js'
const composeEnhancers =
typeof window === 'object' &&
window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ ?
window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__({}) : compose;
const enhancer = composeEnhancers(
applyMiddleware(thunk)
);
const store = createStore(reducer, enhancer);
export default store;
//在組件中這麼寫,來執行這個異步的請求
const action = getTodoList();
//store.dispatch會自動執行action,action便是一個異步請求函數
store.dispatch(action);
//在actionCreators.js action文件中這樣寫
export const getTodoList = () => {
//返回一個函數
return (dispatch) => {
axios.get('/todo.json').then((res) => {
const data = res.data;
const action = initListAction(data);
dispatch(action);
})
}
};
六、redux-saga
1.他也是類似於redux-thunk的中間件,但是他的優勢是將所有的action異步操作放在一個文件夾中進行維護
2.在github中進行搜索
3.關於我項目中的配置,當於devtools並存時
//todolist.js
componentDidMount(){
//將這個action讓saga捕獲到,並不是真正的渲染頁面進行的action
const action = getInitList();
store.dispatch(action);
}
//sagas.js中接受到這個action,獲得到異步數據之後才進行真正的初始化action
function* getInitListAction() {
console.log('abc');
const list = [4,2,3];
//這裏的action就是真正的初始化渲染頁面,發給reducer.js中去操作
const action = initList(list);
yield put(action);
}
//generator
function* todoSaga() {
// 第一個參數爲action的value
yield takeEvery(GET_INIT_LIST_ACTION, getInitListAction);
}
export default todoSaga;
//store/index.js
import { createStore ,applyMiddleware ,compose} from 'redux'
import reducer from './reducer'
import createSagaMiddleware from 'redux-saga'
import todoSaga from './sagas';
const sagaMiddleware = createSagaMiddleware();
const composeEnhancers =
typeof window === 'object' &&
window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ ?
window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__({
// Specify extension’s options like name, actionsBlacklist, actionsCreators, serialize...
}) : compose;
const enhancer = composeEnhancers(
applyMiddleware(sagaMiddleware)
);
const store = createStore(reducer, enhancer);
七、react-redux
1.他是redux的一個組件,直接安裝使用即可
可以看一下別人的分享(感謝這個小可愛)https://segmentfault.com/a/1190000017064759
2.mapStateToProps :用來接收store數據的規則,將state映射成props,在子組件中直接用this.props.xx來使用即可
const mapStateToProps = (state) => {
return {
inputValue: state.inputValue,
list: state.list
};
};
mapDispatchToProps:用來向store中傳遞action的改變state的規則,在執行方法時,直接this.props.handleDel即可
const mapDispatchToProps = (dispatch) => {
return {
handleDel(index){
const action={
type:'del_item',
index
}
dispatch(action);
}
}
}
八、關於動畫
import React,{Component,Fragment} from 'react';
import './transition.css';
class Transition extends Component {
constructor(props){
super(props);
this.state = {
show : true
}
this.handleToggle = this.handleToggle.bind(this);
}
render(){
return (
<Fragment>
<div className={this.state.show ? 'show':'hide'}>hello</div>
<button onClick={this.handleToggle}>toggle</button>
</Fragment>
)
}
handleToggle(){
this.setState({
show : this.state.show ? false : true
})
}
}
export default Transition;
1.第一種:過渡動畫
.show{
/* 過度動畫效果 */
/* opacity: 1;
transition: all 1s ease-in; */
}
.hide{
/* opacity: 0;
transition: all 1s ease-in; */
}
2.第二種:css3動畫
.show{
animation: show-item 2s ease-in forwards;
}
.hide{
/*forwards代表最後一幀保留*/
animation: hide-item 2s ease-in forwards;
}
/* css3動畫效果 */
@keyframes hide-item{
0% {
opacity:1;
color:red;
}
50% {
opacity:0.5;
color:blue;
}
100% {
opacity:0;
color: green;
}
}
@keyframes show-item{
0% {
opacity:0;
color:red;
}
50% {
opacity:0.5;
color:blue;
}
100% {
opacity:1;
color:purple;
}
}
3.第三種:用第三方組件 react-transition-group
在github上進行查看,點擊Main documentation
//帶動畫的組件
import { CSSTransition } from 'react-transition-group';
render(){
return (
<Fragment>
<CSSTransition
in={ this.state.show }
timeout={1000}
classNames="fade"
>
<div>hello</div>
</CSSTransition>
<button onClick={this.handleToggle}>toggle</button>
</Fragment>
)
}
//css文件
.fade-enter{
opacity: 0;
}
.fade-enter-active{
opacity: 1;
transition: opacity 1s ease-in;
}
.fade-enter-done{
opacity: 1;
}
.fade-exit {
opacity: 1;
}
.fade-exit-active {
opacity: 0;
transition: opacity 200ms;
}
.fade-exit-done {
opacity: 0;
}