Mapstatetoprops là gì
Actions, reducers, action creators, middleware, pure functions, immutability, những ngoại ngữ làm rối bất kỳ ai nếu chưa biết redux Show Nếu chưa biết tại sao lại sinh ra thằng Redux này, có thể xem ở tuts trước của mình. Chỉ sử dụng State của ReactComponent sẽ build
import React from 'react';
class Counter extends React.Component {
state = { count: 0 }
increment = () => {
this.setState({
count: this.state.count + 1
});
}
decrement = () => {
this.setState({
count: this.state.count - 1
});
}
render() {
return (
Counter
{this.state.count}
Giải thích ngắn gọn cho dễ theo dõi
Thêm ReduxNhư đã đề cập trong tuts trước, Redux lưustatelại trong 1 cáistore, tranh lẫn lộn,storelà nơi lưustate, vàstatedữ liệu. Cài redux và react-redux package
npm install redux react-redux --save
Tại sao phải 2 cái package?, cái redux chỉ cho ta cáistore, để lấy được cáistatera, sử dụng hàmconnecttrongreact-redux, vì redux không phải chỉ làm việc chung được với React thôi không, nó có thể chơi với Vue, Angular không chừng. Bỏ state đi
import React from 'react';
class Counter extends React.Component {
increment = () => {
}
decrement = () => {
}
render() {
return (
Counter
{this.props.count}
connectnó với store thôi
import { connect } from 'react-redux';
// ...
// Viết thêm hàm này
function mapStateToProps(state) {
return {
count: state.count
};
}
// Thay cái
// export default Counter;
// bằng
export default connect(mapStateToProps)(Counter);
Ok vậy là xong phần connect component với các state ở trongstore, chúng ta cần khai báo Store! Bọc toàn bộ cáiAppbên trong componentProvidercủareact-reduxđể tất cả component bên trongAppcó thể sử dụng hàmconnectđể gọi đếnstore
import { Provider } from 'react-redux';
...
const App = () => (
Chưa xong, chúng ta phải setup cái store để đưa vào cho Provider
import { createStore } from 'redux';
const store = createStore();
const App = () => (
Vẫn chưa đủ, thật sự Redux không được thông minh như chúng ta tưởng tượng, lúc đầu mình đã nghĩ rằng khi create store như vậy nó sẽ cho mình những giá trị default bên trong store. Nhưng không chúng ta phải làm tay tất cả. Chúng ta phải cung cấp cho nó 1 hàm gọi làreducer, cái hàmreducernày phảireturnvề một giá trị cho state, luôn phải return state nhé. Bên trongreducerta sẽ xào nấu state theo yêu cầu, nó sẽ nhận state hiện tại và trả về state mới.
const initialState = {
count: 0
};
function reducer(state = initialState, action) {
return state;
}
const store = createStore(reducer);
const App = () => (
ActionAction là gì, nó đóng vai trò như thế nào và nó đến từ đâu? Làm thế nào mà ta đổi giá trịcounter? actionlà 1 JS object nó sẽ cho biết bạn đang muốnordermón nào, như tờ giấy ghiordertrong nhà hàng ấy mà, nó sẽ chưa thông tin món bạn order, đầu bếpreducersẽ dựa vào đó mà xào nấu ra món bạn order
function reducer(state = initialState, action) {
switch(action.type) {
case 'INCREMENT':
return {
count: state.count + 1
};
case 'DECREMENT':
return {
count: state.count - 1
};
default:
return state;
}
}
Reducer sẽ căn cứ vàoaction.typeđể thực hiện thay đổi và trả về state mới, nên nhớ chúng ta phải LUÔN LUÔN trả về state trongreducer, nếu có hay không có thay đổi cũng phải trả vềstate Không bao giờ được phép thay đổi State trực tiếpState là một immutable object, tuyệt đốiKHÔNGthay đổi state như sau
function brokenReducer(state = initialState, action) {
switch(action.type) {
case 'INCREMENT':
// BẬY: đừng thay giá trị bằng kiểu này
state.count++;
return state;
case 'DECREMENT':
// BẬY: đừng thay giá trị bằng kiểu này
state.count--;
return state;
default:
return state;
}
}
Làm như vậy cũng cấm tuyệt đối nhé:
Action từ đâu mà cóAction không tự sinh ra, nó đượcdispatchra từ hàmdispatch. Hàmdispatchthì đặc biệt là nó không được import, mình có thể gọistore.dispatch(someAction), nhưng cái store này thì nó năm ở trong 1 file thôi, Vậy hàmdispatchnày làm sao có đây? Thật ra lúc chúng ta gọiconnectthì hàmconnectcũng đãmapcái hàmdispatchvào trong props của component luôn.
import React from 'react';
import { connect } from 'react-redux';
class Counter extends React.Component {
increment = () => {
this.props.dispatch({ type: 'INCREMENT' });
}
decrement = () => {
this.props.dispatch({ type: 'DECREMENT' });
}
render() {
return (
Counter
{this.props.count}
TopDev via Vuilaptrinh |