<file_sep>const REFRESH_UI = "REFRESH_UI";

export {
    REFRESH_UI
}<file_sep>import React, { Component } from 'react';
import { NavLink, BrowserRouter, Route, Redirect} from 'react-router-dom'

class Culture extends Component {
    render() {
        return (
            <div>
                Culture
            </div>
        );
    }
}

class Contact extends Component {
    render() {
        return (
            <div>
                Contact
            </div>
        );
    }
}

class History extends Component {
    render() {
        return (
            <div>
                History
            </div>
        );
    }
}

class Recommend extends Component {
    render() {
        return (
            <div>
                Recommend123
            </div>
        );
    }
}

class Music extends Component {
    render() {
        return (
            <div>
               Music
            </div>
        );
    }
}

class Home extends Component {
    render() {
        return (
            <div>
                <NavLink exact to="/" activeStyle={{ color: "purple", fontSize: "30px" }}>Recommend</NavLink>
                <NavLink  to="/home/music" activeStyle={{ color: "purple", fontSize: "30px" }}>Music</NavLink>
                
                <Route  exact path="/" component={Recommend}></Route>
                <Route  path="/home/music" component={Music}></Route>
            </div>
        );
    }
}

class About extends Component {
    render() {
        return (
            <div>
                <NavLink exact to="/about" activeStyle={{ color: "purple", fontSize: "30px" }}>Culture</NavLink>
                <NavLink to="/about/history" activeStyle={{ color: "purple", fontSize: "30px" }}>History</NavLink>
                <NavLink to="/about/contact" activeStyle={{ color: "purple", fontSize: "30px" }}>Contact</NavLink>

                <Route path="/about" component={Culture}></Route>
                <Route path="/about/history" component={History}></Route>
                <Route path="/about/contact" component={Contact}></Route>
            </div>
        );
    }
}

class Me extends Component {
    constructor(props) {
        super(props)

        this.state = {
            isLogin: false,
        }
    }

    render() {
        const { isLogin }  = this.state
        return isLogin ? (
            <div>
                Me
            </div>
        ) : <Redirect to="/login" />
    }
}


class Detail extends Component {
  render() {
    const location = this.props.location
    console.log(location.state);

      return (
          <div>
              {"name:" + location.state.name +  "  age:" + location.state.age}
          </div>
      )
  }
}


class Login extends Component {
    render() {
        return (
            <div>
                Login
            </div>
        );
    }
}


class App extends Component {
    render() {
        return (
            <div>
                <BrowserRouter>
                    {/* <Link to="/">Home</Link>
            <Link to="/about">About</Link>
            <Link to="/me">Me</Link> */}

                    {/* NavLink模糊匹配  */}
                    <NavLink exact to="/" activeStyle={{ color: "red", fontSize: "30px" }}>Home</NavLink>
                    {/* 传参方式1  
                     <NavLink to="/detail?name=mjk" activeStyle={{ color: "red", fontSize: "30px" }}>Detail</NavLink> 
                    */}
                    {/* 传参方式2  */}
                    <NavLink to= {{
                                pathname : "/detail", 
                                search: "?name=mjk",
                                state : {name : "mjk", age : 25}
                            }} 
                            activeStyle={{ color: "red", fontSize: "30px" }}>Detail</NavLink> 
                    <NavLink to="/about" activeStyle={{ color: "red", fontSize: "30px" }}>About</NavLink>
                    <NavLink to="/me" activeStyle={{ color: "red", fontSize: "30px" }}>Me</NavLink>

                    <Route path="/" component={Home}></Route>
                    <Route path="/detail" component={Detail}></Route>
                    <Route path="/about" component={About}></Route>
                    <Route path="/me" component={Me}></Route>
                    <Route path="/login" component={Login}></Route>
                </BrowserRouter>
            </div>
        );
    }
}

export default App;<file_sep>import {
    REFRESH_UI
} from './constants'

const defaultState = {
    items: ["a"]
}
     
export default function reducer(state = defaultState, action) {
    switch(action.type) {
        case REFRESH_UI: {
            return {...state, items: action.items}
        }
        default: {
            return state
        }
    }
}<file_sep>import { createStore } from 'redux'
import reducer from './reducer'

const store = createStore(reducer);

//patch logging
function patchLogging(store) {
    const next = store.dispatch;
    function dispatchAndLogging(action) {
        console.log("logging before---dispatching action:", action);
        next(action);
        console.log("logging after---new state:", store.getState());
    }

    return dispatchAndLogging;
}

// patch thunk
function patchThunk(store) {
    const next = store.dispatch;

    function dispatchAndThunk(action) {
        console.log("thunk before---dispatching action:", action);
        if (typeof action === "function") {
            action(store.dispatch, store.getState)
        } else {
            next(action);
        }
        console.log("thunk after---new state:", store.getState());
    }

    return dispatchAndThunk;
}

// 5.封装applyMiddleware
function applyMiddlewares(...middlewares) {
    const newMiddlewares =  middlewares.reverse()

    newMiddlewares.forEach(middleware => {
        store.dispatch = middleware(store);
    })
}

applyMiddlewares(patchLogging, patchThunk);

export default store;<file_sep>import React, { PureComponent } from 'react'
import connect from './utils/connect'

import {
    incrementAction,
  } from './store/actionCreators'
  
class Header extends PureComponent {
    render() {
        return (
            <div>   
                <h1>计数器:{this.props.counter}</h1>
                <button onClick={(e) => this.props.increment(2)}>+2</button>
            </div>
        );
    }
}

const mapStateToProps = (state) => ({
    counter: state.counter
})

const mapDispachToProps = (dispatch) => ({
    increment(num) {
        dispatch(incrementAction(num))
    }
})
export default connect(mapStateToProps, mapDispachToProps)(Header)<file_sep># ReactStudy
每个项目下执行下面的两个命令就OK
1. yarn install
2. yarn start
<file_sep>import {createStore, applyMiddleware, compose} from 'redux'
import thunkMiddleware from 'redux-thunk';
import reducer from './reducer'

//react devtools
const composeEnhancers = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__({trace: true}) || compose;
const storeEnhancer = applyMiddleware(thunkMiddleware);
const store = createStore(reducer, composeEnhancers(storeEnhancer));

export default store;<file_sep>import React, { PureComponent } from 'react'
import connect from './utils/connect'

import {
    decrementAction,
  } from './store/actionCreators'
  
class Bottom extends PureComponent {
    render() {
        return (
            <div>   
                <h1>计数器:{this.props.counter}</h1>
                <button onClick={(e) => this.props.decrement(2)}>-2</button>
            </div>
        );
    }
}

const mapStateToProps = (state) => ({
    counter: state.counter
})

const mapDispachToProps = (dispatch) => ({
    decrement(num) {
        dispatch(decrementAction(num))
    }
})

export default connect(mapStateToProps, mapDispachToProps)(Bottom)<file_sep>import React, { memo, useState, useCallback } from 'react';

const MJKButton = memo((props) => {
    console.log("MJKButton重新渲染: " + props.title);

    return (
        <button onClick={props.increment}>{props.title} +1</button>
    ) 
});


function App() {
    console.log("App重新渲染");

    const [count, setCount] = useState(0);
    const [show, setShow] = useState(true);

    const increment1 = () => {
        console.log("执行increment1函数");
        setCount(count + 1);
    }
    
      const increment2 = useCallback(() => {
        console.log("执行increment2函数");
        setCount(count + 1);
      }, [count]);
    
      return (
        <div>
          <h2>HookCallback: {count}</h2>
          <MJKButton title="btn1" increment={increment1}/>
          <MJKButton title="btn2" increment={increment2}/>
    
          <button onClick={e => setShow(!show)}>show切换</button>
        </div>
      )
}

export default App;<file_sep>import React, { PureComponent } from 'react'
import { connect } from 'react-redux'

import {
    incrementAction,
  } from './store/counter/actionCreators'
  
class Counter extends PureComponent {
    render() {
        return (
            <div>   
                <h1>计数器:{this.props.counter}</h1>
                <button onClick={(e) => this.props.increment(2)}>+2</button>
            </div>
        );
    }
}

const mapStateToProps = (state) => ({
    counter: state.counterInfo.counter
})

const mapDispachToProps = (dispatch) => ({
    increment(num) {
        dispatch(incrementAction(num))
    }
})

export default connect(mapStateToProps, mapDispachToProps)(Counter)<file_sep>import React, { Component } from 'react'
import { connect } from 'react-redux'
import {
    requestDataAction
} from './store/home/actionCreators'

class Home extends Component {
    render() {
        return (
            <div>
                <ul>
                    {
                        this.props.items.map((item, index, arr) => {
                            return (
                                <li key={item}> {item}</li>
                            )
                        })
                    }
                </ul>
                <button onClick={(e) => this.props.requestData()}>请求数据</button>
            </div>
        )
    }
}

const mapStateToProps = (state) => ({
    items: state.homeInfo.items
})

//redux-thunk传的是函数
const mapDispatchToProps = (dispatch) => ({
    requestData() {
        dispatch(requestDataAction)
    }
})

export default connect(mapStateToProps, mapDispatchToProps)(Home)<file_sep>import React, { Component } from 'react'
import axios from 'axios'
export default class App extends Component {
    render() {
        return (
            <div>
                Hello
            </div>
        )
    }

    componentDidMount() {
        // axios.post("https://httpbin.org/post", {
        //     name: "lucy",
        //     age: 28
        // }).then(response => {
        //     console.log(response);
        // })(error => {
        //     console.log(error);
        // });

        axios({
            url: "https://httpbin.org/post",
            data: {
                name: "mjk",
                age: 40
            },
            method: "post"
        }).then(res => {
            console.log(res);
        }).catch(err => {
            console.error(err);
        })
    }
}
<file_sep>import React, { PureComponent } from 'react'

import store from './store/'
import {
    incrementAction,
    decrementAction
  } from './store/actionCreators'
  
class Header extends PureComponent {
    constructor(props) {
        super(props)

        this.state = {
            counter: store.getState().counter
        }
    }

    componentDidMount() {
        this.unsubscribue = store.subscribe(() => {
            this.setState({
                counter: store.getState().counter
            })
        })
    }
    
    
    componentWillUnmount() {
        this.unsubscribue()
    }

    render() {
        return (
            <div>   
                <h1>计数器:{this.state.counter}</h1>
                <button onClick={(e) => store.dispatch(incrementAction(2))}>+2</button>
            </div>
        );
    }
}

class Bottom extends PureComponent {
    constructor(props) {
        super(props)

        this.state = {
            counter: store.getState().counter
        }
    }

    componentDidMount() {
        this.unsubscribue = store.subscribe(() => {
            this.setState({
                counter: store.getState().counter
            })
        })
    }
    
    componentWillUnmount() {
        this.unsubscribue()
    }

    render() {
        return (
            <div>   
                <h1>计数器:{this.state.counter}</h1>
                <button onClick={(e) => store.dispatch(decrementAction(2))}>-2</button>
            </div>
        );
    }
}

export default class App extends PureComponent {
    render() {
        console.log(store.getState().counter)
        return (
            <div>
                <Header/>
                <Bottom/>
            </div>
        )
    }
}
