forked from YvetteLau/Blog
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
26 changed files
with
444 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
{ | ||
"name": "counter", | ||
"version": "0.1.0", | ||
"private": true, | ||
"dependencies": { | ||
"react": "^16.10.1", | ||
"react-dom": "^16.10.1", | ||
"react-redux": "^7.1.1", | ||
"react-scripts": "3.1.2", | ||
"redux": "^4.0.4", | ||
"redux-logger": "^3.0.6", | ||
"redux-persist": "^6.0.0", | ||
"redux-promise": "^0.6.0", | ||
"redux-thunk": "^2.3.0" | ||
}, | ||
"scripts": { | ||
"start": "react-scripts start", | ||
"build": "react-scripts build", | ||
"test": "react-scripts test", | ||
"eject": "react-scripts eject" | ||
}, | ||
"eslintConfig": { | ||
"extends": "react-app" | ||
}, | ||
"browserslist": { | ||
"production": [ | ||
">0.2%", | ||
"not dead", | ||
"not op_mini all" | ||
], | ||
"development": [ | ||
"last 1 chrome version", | ||
"last 1 firefox version", | ||
"last 1 safari version" | ||
] | ||
} | ||
} |
Binary file not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
<!DOCTYPE html> | ||
<html lang="en"> | ||
<head> | ||
<meta charset="utf-8" /> | ||
<link rel="shortcut icon" href="%PUBLIC_URL%/favicon.ico" /> | ||
<meta name="viewport" content="width=device-width, initial-scale=1" /> | ||
<meta name="theme-color" content="#000000" /> | ||
<meta | ||
name="description" | ||
content="Web site created using create-react-app" | ||
/> | ||
<link rel="apple-touch-icon" href="logo192.png" /> | ||
<!-- | ||
manifest.json provides metadata used when your web app is installed on a | ||
user's mobile device or desktop. See https://developers.google.com/web/fundamentals/web-app-manifest/ | ||
--> | ||
<link rel="manifest" href="%PUBLIC_URL%/manifest.json" /> | ||
<style> | ||
button{ | ||
height: 40px; | ||
width: 80px; | ||
background: pink; | ||
text-align: center; | ||
outline: none; | ||
border: 0; | ||
margin-right: 10px; | ||
} | ||
</style> | ||
<title>React App</title> | ||
</head> | ||
<body> | ||
<noscript>You need to enable JavaScript to run this app.</noscript> | ||
<div id="root"></div> | ||
</body> | ||
</html> |
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
{ | ||
"short_name": "React App", | ||
"name": "Create React App Sample", | ||
"icons": [ | ||
{ | ||
"src": "favicon.ico", | ||
"sizes": "64x64 32x32 24x24 16x16", | ||
"type": "image/x-icon" | ||
}, | ||
{ | ||
"src": "logo192.png", | ||
"type": "image/png", | ||
"sizes": "192x192" | ||
}, | ||
{ | ||
"src": "logo512.png", | ||
"type": "image/png", | ||
"sizes": "512x512" | ||
} | ||
], | ||
"start_url": ".", | ||
"display": "standalone", | ||
"theme_color": "#000000", | ||
"background_color": "#ffffff" | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
# https://www.robotstxt.org/robotstxt.html | ||
User-agent: * |
41 changes: 41 additions & 0 deletions
41
myreact-redux/counter/src/components/Counter-no-react-redux.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
import React from 'react'; | ||
import store from '../store'; | ||
import actions from '../store/actions/counter'; | ||
/** | ||
* reducer 是 combineReducer({counter, ...}) | ||
* state 的结构为 | ||
* { | ||
* counter: {number: 0}, | ||
* .... | ||
* } | ||
*/ | ||
class Counter extends React.Component { | ||
constructor(props) { | ||
super(props); | ||
this.state = { | ||
number: store.getState().counter.number | ||
} | ||
} | ||
componentDidMount() { | ||
this.unsub = store.subscribe(() => { | ||
if(this.state.number === store.getState().counter.number) { | ||
return; | ||
} | ||
this.setState({ | ||
number: store.getState().counter.number | ||
}); | ||
}); | ||
} | ||
render() { | ||
return ( | ||
<div> | ||
<p>{`number: ${this.state.number}`}</p> | ||
<button onClick={() => {store.dispatch(actions.add(2))}}>+</button> | ||
<button onClick={() => {store.dispatch(actions.minus(2))}}>-</button> | ||
<div> | ||
) | ||
} | ||
componentWillUnmount() { | ||
this.unsub(); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
import React, { Component } from 'react'; | ||
import { connect } from '../react-redux'; | ||
import actions from '../store/actions/counter'; | ||
|
||
class Counter extends Component { | ||
render() { | ||
return ( | ||
<div> | ||
<p>{`number: ${this.props.number}`}</p> | ||
<button onClick={() => { this.props.add(2) }}>+</button> | ||
<button onClick={() => { this.props.minus(2) }}>-</button> | ||
</div> | ||
) | ||
} | ||
} | ||
|
||
const mapStateToProps = state => ({ | ||
number: state.counter.number | ||
}); | ||
|
||
export default connect(mapStateToProps, actions)(Counter); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
import React, { Component } from 'react'; | ||
import { connect } from '../react-redux'; | ||
|
||
class Page extends Component { | ||
render() { | ||
console.log(this.props.store); | ||
return ( | ||
<div>Page</div> | ||
) | ||
} | ||
} | ||
|
||
export default connect(()=>({}), ()=>({}))(Page); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
import React from 'react'; | ||
import ReactDOM from 'react-dom'; | ||
import {Provider} from './react-redux'; | ||
import Counter from './components/Counter'; | ||
import store from './store'; | ||
|
||
|
||
|
||
ReactDOM.render(<Provider store={store}><Counter /></Provider>, document.getElementById('root')); | ||
|
28 changes: 28 additions & 0 deletions
28
myreact-redux/counter/src/react-redux/components/Provider.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
import React, { Component } from 'react'; | ||
import storeShape from '../utils/storeShape'; | ||
|
||
export default class Provider extends Component { | ||
static childContextTypes = { | ||
store: storeShape.isRequired | ||
} | ||
|
||
constructor(props) { | ||
super(props); | ||
this.store = props.store; | ||
} | ||
|
||
getChildContext() { | ||
return { | ||
store: this.store | ||
} | ||
} | ||
|
||
render() { | ||
/** | ||
* 早前返回的是 return Children.only(this.props.children) | ||
* 导致Provider只能包裹一个子组件,后来取消了此限制 | ||
* 因此此处,我们直接返回 this.props.children | ||
*/ | ||
return this.props.children | ||
} | ||
} |
61 changes: 61 additions & 0 deletions
61
myreact-redux/counter/src/react-redux/components/connect.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,61 @@ | ||
import React, { Component } from 'react'; | ||
import { bindActionCreators } from 'redux'; | ||
import storeShape from '../utils/storeShape'; | ||
import shallowEqual from '../utils/shallowEqual'; | ||
/** | ||
* mapStateToProps 默认不关联state | ||
* mapDispatchToProps 默认值为 dispatch => ({dispatch}),将 `store.dispatch` 方法作为属性传递给组件 | ||
*/ | ||
const defaultMapStateToProps = state => ({}); | ||
const defaultMapDispatchToProps = dispatch => ({ dispatch }); | ||
function getDisplayName(WrappedComponent) { | ||
return WrappedComponent.displayName || WrappedComponent.name || 'Component'; | ||
} | ||
|
||
export default function connect(mapStateToProps, mapDispatchToProps) { | ||
if(!mapStateToProps) { | ||
mapStateToProps = defaultMapStateToProps; | ||
} | ||
if (!mapDispatchToProps) { | ||
//当 mapDispatchToProps 为 null/undefined/false...时,使用默认值 | ||
mapDispatchToProps = defaultMapDispatchToProps; | ||
} | ||
return function wrapWithConnect(WrappedComponent) { | ||
return class Connect extends Component { | ||
static contextTypes = { | ||
store: storeShape | ||
}; | ||
static displayName = `Connect(${getDisplayName(WrappedComponent)})`; | ||
|
||
constructor(props, context) { | ||
super(props, context); | ||
this.store = context.store; | ||
//源码中是将 store.getState() 给了 this.state | ||
this.state = mapStateToProps(this.store.getState(), this.props); | ||
if (typeof mapDispatchToProps === 'function') { | ||
this.mappedDispatch = mapDispatchToProps(this.store.dispatch, this.props); | ||
} else { | ||
//传递了一个 actionCreator 对象过来 | ||
this.mappedDispatch = bindActionCreators(mapDispatchToProps, this.store.dispatch); | ||
} | ||
} | ||
componentDidMount() { | ||
this.unsub = this.store.subscribe(() => { | ||
const mappedState = mapStateToProps(this.store.getState()); | ||
if (shallowEqual(this.state, mappedState)) { | ||
return; | ||
} | ||
this.setState(mappedState); | ||
}); | ||
} | ||
componentWillUnmount() { | ||
this.unsub(); | ||
} | ||
render() { | ||
return ( | ||
<WrappedComponent {...this.props} {...this.state} {...this.mappedDispatch} /> | ||
) | ||
} | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
// Provider 通过context提供store | ||
// connect 连接仓库和组件,仓库的取值和订阅逻辑都放在在里面 | ||
import connect from './components/connect'; | ||
import Provider from './components/Provider'; | ||
|
||
export { | ||
connect, | ||
Provider | ||
} |
22 changes: 22 additions & 0 deletions
22
myreact-redux/counter/src/react-redux/utils/shallowEqual.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
export default function shallowEqual(objA, objB) { | ||
if (objA === objB) { | ||
return true | ||
} | ||
|
||
const keysA = Object.keys(objA) | ||
const keysB = Object.keys(objB) | ||
|
||
if (keysA.length !== keysB.length) { | ||
return false | ||
} | ||
|
||
const hasOwn = Object.prototype.hasOwnProperty | ||
for (let i = 0; i < keysA.length; i++) { | ||
if (!hasOwn.call(objB, keysA[i]) || | ||
objA[keysA[i]] !== objB[keysA[i]]) { | ||
return false | ||
} | ||
} | ||
|
||
return true | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
import PropTypes from 'prop-types' | ||
|
||
export default PropTypes.shape({ | ||
subscribe: PropTypes.func.isRequired, | ||
dispatch: PropTypes.func.isRequired, | ||
getState: PropTypes.func.isRequired | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
const applyMiddleware = (...middlewares) => createStore => (...args) => { | ||
let store = createStore(...args); | ||
let dispatch; | ||
const middlewareAPI = { | ||
getState: store.getState, | ||
dispatch: (...args) => dispatch(...args) | ||
} | ||
let middles = middlewares.map(middle => middle(middlewareAPI)); | ||
dispatch = middles.reduceRight((prev, current) => current(prev), store.dispatch); | ||
return { | ||
...store, | ||
dispatch | ||
} | ||
} | ||
|
||
export default applyMiddleware; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
export default function combineReducers(reducers) { | ||
//返回 reducer | ||
return function combination(state = {}, action) { | ||
let hasChanged = false; | ||
let nextState = {}; | ||
for(let key in reducers) { | ||
const previousStateForKey = state[key]; | ||
const nextStateForKey = reducers[key](previousStateForKey, action); | ||
nextState[key] = nextStateForKey; | ||
hasChanged = hasChanged || previousStateForKey !== nextStateForKey; | ||
} | ||
return hasChanged ? nextState : state; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
export default function compose(...fns) { | ||
if(fns.length === 0) { | ||
return args => args | ||
} | ||
if(fns.length === 1) { | ||
return fn[0]; | ||
} | ||
return fns.reduce((a, b) => (...args) => a(b(...args))); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
export default function createStore(reducer, preloadState, enhancer) { | ||
let state; | ||
let listeners = []; | ||
|
||
const dispatch = action => { | ||
state = reducer(state, action); | ||
listeners.forEach(ln => ln()); | ||
} | ||
const getState = () => { | ||
return state | ||
}; | ||
const subscribe = listen => { | ||
listeners.push(listen); | ||
return function unsubscribe() { | ||
listeners = listeners.filter(ln => ln !== listen); | ||
return listeners; | ||
} | ||
} | ||
dispatch({type: '@@REDUX/__INIT__'}); | ||
return { | ||
getState, | ||
dispatch, | ||
subscribe | ||
} | ||
} |
Oops, something went wrong.