├── .vscode └── settings.json ├── README.md ├── src ├── config │ └── api.js ├── index.css ├── utils │ └── http.js ├── list │ ├── action │ │ └── index.js │ ├── store.js │ ├── comp │ │ ├── cLists.js │ │ ├── app.js │ │ ├── list.js │ │ └── addList.js │ ├── index.jsx │ └── reducer │ │ └── index.js ├── redux-study │ ├── store │ │ └── store.js │ ├── components │ │ ├── App.js │ │ ├── Footer.js │ │ ├── Link.js │ │ ├── Todo.js │ │ └── TodoList.js │ ├── index.js │ ├── container │ │ ├── FilterLink.js │ │ ├── AddTodo.js │ │ └── VisibleTodoList.js │ ├── actions │ │ └── action.js │ └── reduces │ │ └── reduces.js ├── liferecycle │ ├── test.jsx │ ├── createRef.jsx │ ├── dom.jsx │ └── index.jsx ├── redux-test │ ├── reducer │ │ ├── index.js │ │ ├── visibilityFilter.js │ │ └── todos.js │ ├── container │ │ ├── AddTodo.js │ │ ├── LinkInfo.js │ │ └── ListInfo.js │ ├── App.js │ ├── components │ │ ├── Footer.js │ │ ├── AddList.js │ │ ├── Link.js │ │ └── ListInfoDetail.js │ └── actions │ │ └── index.js ├── redux │ ├── reducers │ │ ├── index.js │ │ ├── visibilityFilter.js │ │ └── todos.js │ ├── index.js │ ├── components │ │ ├── App.js │ │ ├── Todo.js │ │ ├── Footer.js │ │ ├── Link.js │ │ └── TodoList.js │ ├── actions │ │ └── index.js │ ├── containers │ │ ├── FilterLink.js │ │ ├── AddTodo.js │ │ ├── UnDo.js │ │ └── VisibleTodoList.js │ └── selector.js ├── App.test.js ├── redux-demo │ ├── reducer.js │ ├── index.js │ └── count.js ├── gaojie │ ├── extends.jsx │ ├── refs1.jsx │ ├── test.jsx │ ├── refs.jsx │ ├── ele.jsx │ └── index.jsx ├── router │ ├── mainContent.js │ └── index.js ├── render │ ├── testrender.jsx │ └── index.jsx ├── todolist │ ├── list.js │ ├── search.js │ └── todo.js ├── async-action │ ├── action.js │ ├── reduce.js │ ├── sagas.js │ ├── Image.js │ └── index.js ├── App.css ├── transition │ ├── sider.jsx │ ├── transition.css │ └── index.jsx ├── boundaries │ └── index.jsx ├── App.js ├── clickcount │ └── index.js ├── immutable │ └── index.js ├── purecomp │ └── index.jsx ├── context │ ├── index.jsx │ ├── test.jsx │ └── test1.jsx ├── redirect │ └── index.js ├── noctrl │ └── index.jsx ├── renderprop │ ├── index.jsx │ └── comp.jsx ├── refs │ └── index.jsx ├── portals │ └── index.jsx ├── extends │ └── index.jsx ├── index.js ├── stateup │ └── index.jsx ├── logo.svg └── registerServiceWorker.js ├── public ├── favicon.ico ├── manifest.json └── index.html ├── .babelrc ├── .gitignore └── package.json /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | } -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # react-study 2 | 开始正式学习react了 虽然工作中暂时用不到 但还是要学习 3 | -------------------------------------------------------------------------------- /src/config/api.js: -------------------------------------------------------------------------------- 1 | const API = { 2 | SEARCH_MUSIC: '/search' 3 | } -------------------------------------------------------------------------------- /public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IFmiss/react-study/master/public/favicon.ico -------------------------------------------------------------------------------- /src/index.css: -------------------------------------------------------------------------------- 1 | body { 2 | margin: 0; 3 | padding: 0; 4 | font-family: sans-serif; 5 | } 6 | -------------------------------------------------------------------------------- /src/utils/http.js: -------------------------------------------------------------------------------- 1 | import axios from 'axios' 2 | axios.defaults.baseURL = 'http://localhost:4000' 3 | export default axios -------------------------------------------------------------------------------- /src/list/action/index.js: -------------------------------------------------------------------------------- 1 | export function AddList (value) { 2 | return { 3 | type: 'ADD_TODO', 4 | value 5 | } 6 | } -------------------------------------------------------------------------------- /.babelrc: -------------------------------------------------------------------------------- 1 | 2 | { 3 | "presets": ["env","react"], 4 | "plugins": ["transform-decorators-legacy","transform-class-properties"] 5 | } -------------------------------------------------------------------------------- /src/list/store.js: -------------------------------------------------------------------------------- 1 | import {createStore} from 'redux' 2 | import addTodo from './reducer' 3 | 4 | const store = createStore(addTodo) 5 | export default store -------------------------------------------------------------------------------- /src/redux-study/store/store.js: -------------------------------------------------------------------------------- 1 | import {createStore} from 'redux' 2 | import todoApp from './../reduces/reduces' 3 | 4 | const store = createStore(todoApp) 5 | 6 | export default store 7 | -------------------------------------------------------------------------------- /src/liferecycle/test.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | class TestJsx extends React.PureComponent{ 3 | render() { 4 | return ( 5 |

React TestJsx PureComponent

6 | ) 7 | } 8 | } 9 | export default TestJsx -------------------------------------------------------------------------------- /src/redux-test/reducer/index.js: -------------------------------------------------------------------------------- 1 | import {combineReducers} from 'redux' 2 | import todos from './todos' 3 | import visibilityFilter from './visibilityFilter' 4 | 5 | export default combineReducers({ 6 | todos, 7 | visibilityFilter 8 | }) -------------------------------------------------------------------------------- /src/redux/reducers/index.js: -------------------------------------------------------------------------------- 1 | import { combineReducers } from 'redux' 2 | import todos from './todos' 3 | import visibilityFilter from './visibilityFilter' 4 | 5 | const todoApp = combineReducers({ 6 | todos, 7 | visibilityFilter 8 | }) 9 | 10 | export default todoApp -------------------------------------------------------------------------------- /src/App.test.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ReactDOM from 'react-dom'; 3 | import App from './App'; 4 | it('renders without crashing', () => { 5 | const div = document.createElement('div'); 6 | ReactDOM.render(, div); 7 | ReactDOM.unmountComponentAtNode(div); 8 | }); 9 | -------------------------------------------------------------------------------- /src/redux-demo/reducer.js: -------------------------------------------------------------------------------- 1 | function counter(state = { count: 0 }, action) { 2 | let count = state.count 3 | switch (action.type) { 4 | case 'increase': 5 | return { count: count + 1 } 6 | default: 7 | return { count: count } 8 | } 9 | } 10 | 11 | export default counter -------------------------------------------------------------------------------- /src/redux/reducers/visibilityFilter.js: -------------------------------------------------------------------------------- 1 | const visibilityFilter = (state = 'SHOW_ALL', action) => { 2 | switch (action.type) { 3 | case 'SET_VISIBILITY_FILTER': 4 | return action.filter 5 | default: 6 | return state 7 | } 8 | } 9 | export default visibilityFilter 10 | -------------------------------------------------------------------------------- /src/list/comp/cLists.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import {connect} from 'react-redux' 3 | import List from './list' 4 | 5 | const mapStateToProps = (state, ownProps) => { 6 | return { 7 | lists: state 8 | } 9 | } 10 | 11 | const CList = connect(mapStateToProps, null)(List) 12 | export default CList -------------------------------------------------------------------------------- /src/gaojie/extends.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | export default (data) => (Comp) => class ExtendsComp extends Comp{ 3 | componentDidMount () { 4 | console.log('extendsComp',this.state) 5 | } 6 | render() { 7 | return ( 8 |
9 | {data} 10 |
11 | ) 12 | } 13 | } -------------------------------------------------------------------------------- /src/list/comp/app.js: -------------------------------------------------------------------------------- 1 | import AddList from './addList' 2 | import React from 'react' 3 | import Clists from './cLists' 4 | class App extends React.Component{ 5 | render() { 6 | return( 7 |
8 | 9 | 10 |
11 | ) 12 | } 13 | } 14 | export default App -------------------------------------------------------------------------------- /src/list/index.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import {render} from 'react-dom' 3 | import store from './store' 4 | import APP from './comp/app' 5 | import { Provider } from 'react-redux' 6 | 7 | render( 8 | 9 | 10 | , 11 | document.getElementById('redux') 12 | ) 13 | -------------------------------------------------------------------------------- /src/list/reducer/index.js: -------------------------------------------------------------------------------- 1 | import {AddList} from './../action' 2 | function addTodo (state = [], action) { 3 | switch (action.type) { 4 | case 'ADD_TODO': 5 | return [ 6 | action.value, 7 | ...state 8 | ] 9 | default: 10 | return state 11 | } 12 | } 13 | export default addTodo -------------------------------------------------------------------------------- /src/redux-test/reducer/visibilityFilter.js: -------------------------------------------------------------------------------- 1 | 2 | // let addId = 0 3 | const visibilityFilter = (state = 'SHOW_ALL', action) => { 4 | switch (action.type) { 5 | case 'SET_VISIBILITY_FILTER': 6 | return action.filter 7 | default: 8 | return state 9 | } 10 | } 11 | 12 | export default visibilityFilter -------------------------------------------------------------------------------- /src/redux-demo/index.js: -------------------------------------------------------------------------------- 1 | import {Provider} from 'react-redux' 2 | import {createStore} from 'redux' 3 | import Counter from './redux-demo/reducer' 4 | import App from './redux-demo/count' 5 | 6 | let store = createStore(Counter) 7 | 8 | render( 9 | 10 | 11 | , 12 | document.getElementById('root') 13 | ) -------------------------------------------------------------------------------- /src/redux-test/container/AddTodo.js: -------------------------------------------------------------------------------- 1 | import {addList} from './../actions' 2 | import { connect } from 'react-redux' 3 | import AddList from './../components/AddList' 4 | 5 | const mapDispatchToProps = (dispatch) => { 6 | return { 7 | onSubmit: (text) => dispatch(addList(text)) 8 | } 9 | } 10 | 11 | export default connect(null , mapDispatchToProps)(AddList) -------------------------------------------------------------------------------- /src/router/mainContent.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import {Route} from 'react-router-dom' 3 | import Todo from './../todolist/todo' 4 | class MainContent extends React.Component{ 5 | render () { 6 | return ( 7 |
8 | 9 |
10 | ) 11 | } 12 | } 13 | 14 | export default MainContent -------------------------------------------------------------------------------- /src/list/comp/list.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | class Lists extends React.Component{ 3 | render () { 4 | const {lists} = this.props 5 | return( 6 |
7 | { 8 | lists.map((item, index) => ( 9 |

{item}

10 | )) 11 | } 12 |
13 | ) 14 | } 15 | } 16 | export default Lists -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/ignore-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | /node_modules 5 | 6 | # testing 7 | /coverage 8 | 9 | # production 10 | /build 11 | 12 | # misc 13 | .DS_Store 14 | .env.local 15 | .env.development.local 16 | .env.test.local 17 | .env.production.local 18 | 19 | npm-debug.log* 20 | yarn-debug.log* 21 | yarn-error.log* 22 | -------------------------------------------------------------------------------- /public/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "short_name": "React App", 3 | "name": "Create React App Sample", 4 | "icons": [ 5 | { 6 | "src": "favicon.ico", 7 | "sizes": "64x64 32x32 24x24 16x16", 8 | "type": "image/x-icon" 9 | } 10 | ], 11 | "start_url": "./index.html", 12 | "display": "standalone", 13 | "theme_color": "#000000", 14 | "background_color": "#ffffff" 15 | } 16 | -------------------------------------------------------------------------------- /src/redux-study/components/App.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import Footer from './Footer' 3 | import AddTodo from './../container/AddTodo' 4 | import VisibilityTodoList from './../container/VisibleTodoList' 5 | 6 | const App = () => { 7 | return ( 8 |
9 | 10 | 11 |
12 |
13 | ) 14 | } 15 | 16 | export default App -------------------------------------------------------------------------------- /src/gaojie/refs1.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | export default (WrappedComp) => class LogProps extends React.Component{ 3 | componentDidUpdate(prevProps) { 4 | console.log('old props: ', prevProps) 5 | console.log('new propsL: ', this.props) 6 | } 7 | 8 | render() { 9 | return ( 10 |
11 | 12 |
13 | ) 14 | } 15 | } -------------------------------------------------------------------------------- /src/redux-test/App.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import AddTodo from './container/AddTodo' 3 | import ListInfo from './container/ListInfo' 4 | import Footer from './components/Footer' 5 | 6 | class App extends React.Component{ 7 | render(){ 8 | return ( 9 |
10 | 11 | 12 |
13 |
14 | ) 15 | } 16 | } 17 | export default App -------------------------------------------------------------------------------- /src/redux/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import { render } from 'react-dom' 3 | import { Provider } from 'react-redux' 4 | import { createStore } from 'redux' 5 | import todoApp from './reducers' 6 | import App from './components/App' 7 | 8 | let store = createStore(todoApp) 9 | 10 | render( 11 | 12 | 13 | , 14 | document.getElementById('test') 15 | ) -------------------------------------------------------------------------------- /src/gaojie/test.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | function withHeader (WrappedComponent) { 3 | return class HOC extends React.Component{ 4 | render() { 5 | return( 6 |
7 |
8 | 我是标题 9 |
10 | 11 |
12 | ) 13 | } 14 | } 15 | } 16 | export default withHeader -------------------------------------------------------------------------------- /src/redux-study/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import { render } from 'react-dom' 3 | import { Provider } from 'react-redux' 4 | import { createStore } from 'redux' 5 | import todoApp from './reduces/reduces' 6 | import App from './components/App' 7 | 8 | let store = createStore(todoApp) 9 | render ( 10 | 11 | 12 | , 13 | document.getElementById('root') 14 | ) -------------------------------------------------------------------------------- /src/redux/components/App.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import Footer from './Footer' 3 | import AddTodo from '../containers/AddTodo' 4 | import VisibleTodoList from '../containers/VisibleTodoList' 5 | import UnDoC from './../containers/UnDo' 6 | 7 | const App = () => ( 8 |
9 | 10 | 11 |
12 | 13 |
14 | ) 15 | 16 | export default App -------------------------------------------------------------------------------- /src/render/testrender.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | class TestRender extends React.Component{ 3 | render() { 4 | console.log('我 re-render 了') 5 | const { name, age } = this.props 6 | return( 7 |
8 | 姓名: 9 | {name} 10 | 年龄: 11 | {age} 12 |
13 | ) 14 | } 15 | } 16 | export default TestRender -------------------------------------------------------------------------------- /src/todolist/list.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | class List extends React.Component{ 3 | constructor (props) { 4 | super(props) 5 | } 6 | render () { 7 | return ( 8 | 15 | ) 16 | } 17 | } 18 | 19 | export default List 20 | -------------------------------------------------------------------------------- /src/async-action/action.js: -------------------------------------------------------------------------------- 1 | import fetch from 'cross-fetch' 2 | // 请求地址 3 | export function fetchBingInfo (url) { 4 | return { 5 | type: 'FETCH_POSTS', 6 | url 7 | } 8 | } 9 | 10 | export function fetchError (error) { 11 | return { 12 | type: 'FETCH_ERROR', 13 | error 14 | } 15 | } 16 | 17 | export function fetchSuccess (data) { 18 | return { 19 | type: 'FETCH_SUCCESS', 20 | data 21 | } 22 | } -------------------------------------------------------------------------------- /src/gaojie/refs.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | export default (WrappedComp) => class RefsHOC extends React.Component{ 3 | proc = (wrappedCompInstance) => { 4 | // wrappedCompInstance.method() 5 | console.log(wrappedCompInstance) 6 | } 7 | render() { 8 | const props = Object.assign({}, this.props, { 9 | name: '戴伟' 10 | }) 11 | return this.headerDemo = ref}/> 12 | } 13 | } -------------------------------------------------------------------------------- /src/todolist/search.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | class Search extends React.Component{ 3 | constructor (props) { 4 | super(props) 5 | } 6 | onKeyDown = (e) => { 7 | this.onEnter(e) 8 | } 9 | onEnter = (e) => { 10 | if (e.keyCode !== 13) return 11 | this.props.setData(e.target.value) 12 | e.target.value = '' 13 | } 14 | render () { 15 | return 16 | } 17 | } 18 | export default Search -------------------------------------------------------------------------------- /src/App.css: -------------------------------------------------------------------------------- 1 | .App { 2 | text-align: center; 3 | } 4 | 5 | .App-logo { 6 | animation: App-logo-spin infinite 20s linear; 7 | height: 80px; 8 | } 9 | 10 | .App-header { 11 | background-color: #222; 12 | height: 150px; 13 | padding: 20px; 14 | color: white; 15 | } 16 | 17 | .App-title { 18 | font-size: 1.5em; 19 | } 20 | 21 | .App-intro { 22 | font-size: large; 23 | } 24 | 25 | @keyframes App-logo-spin { 26 | from { transform: rotate(0deg); } 27 | to { transform: rotate(360deg); } 28 | } 29 | -------------------------------------------------------------------------------- /src/redux/components/Todo.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import PropTypes from 'prop-types' 3 | 4 | const Todo = ({onClick, completed, text}) => ( 5 |
  • 11 | {text} 12 |
  • 13 | ) 14 | 15 | Todo.propTypes = { 16 | onClick: PropTypes.func.isRequired, 17 | completed: PropTypes.bool.isRequired, 18 | text: PropTypes.string.isRequired 19 | } 20 | 21 | export default Todo -------------------------------------------------------------------------------- /src/transition/sider.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import CSSTransition from 'react-addons-css-transition-group' 3 | class TestCss extends React.Component{ 4 | render () { 5 | return ( 6 |
    7 | 11 | 12 | 13 |
    14 | ) 15 | } 16 | } 17 | export default TestCss -------------------------------------------------------------------------------- /src/boundaries/index.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | class ErrorBoundary extends React.Component{ 3 | constructor(props) { 4 | super(props) 5 | this.state = {hasError: false} 6 | } 7 | 8 | componentDidCatch (error, info) { 9 | this.setState({ 10 | hasError: true 11 | }) 12 | console.log(error, info) 13 | } 14 | 15 | render() { 16 | if (this.state.hasError) { 17 | return

    有些组件出问题了啊

    18 | } 19 | return this.props.children 20 | } 21 | } 22 | export default ErrorBoundary -------------------------------------------------------------------------------- /src/transition/transition.css: -------------------------------------------------------------------------------- 1 | .example-enter { 2 | opacity: 0.01; 3 | } 4 | 5 | .example-enter.example-enter-active { 6 | opacity: 1; 7 | transition: opacity 500ms ease-in; 8 | } 9 | 10 | .example-leave { 11 | opacity: 1; 12 | } 13 | 14 | .example-leave.example-leave-active { 15 | opacity: 0.01; 16 | transition: opacity 300ms ease-in; 17 | } 18 | 19 | 20 | .example-appear { 21 | opacity: 0.01; 22 | } 23 | 24 | .example-appear.example-appear-active { 25 | opacity: 1; 26 | transition: opacity .5s ease-in; 27 | } -------------------------------------------------------------------------------- /src/redux-test/components/Footer.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import LinkInfo from './../container/LinkInfo' 3 | import {VisibilityFilters} from './../actions' 4 | class Footer extends React.Component{ 5 | render () { 6 | return( 7 |
    8 | 9 | Show: 10 | 11 | 12 | 13 | 14 |
    15 | ) 16 | } 17 | } 18 | 19 | export default Footer -------------------------------------------------------------------------------- /src/redux/components/Footer.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import FilterLink from '../containers/FilterLink' 3 | 4 | const Footer = () => { 5 | return ( 6 |

    7 | Show: 8 | {' '} 9 | 10 | ALL 11 | 12 | {', '} 13 | 14 | ACTIVE 15 | 16 | {' '} 17 | 18 | COMPLETED 19 | 20 |

    21 | ) 22 | } 23 | 24 | export default Footer 25 | -------------------------------------------------------------------------------- /src/redux-test/components/AddList.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | 3 | class AddList extends React.Component{ 4 | render () { 5 | const {onSubmit} = this.props 6 | let input 7 | return( 8 |
    { 9 | e.preventDefault() 10 | if (input.value.trim() === '') return 11 | onSubmit(input.value) 12 | input.value = '' 13 | }}> 14 | input = node}/> 15 | 18 |
    19 | ) 20 | } 21 | } 22 | 23 | export default AddList -------------------------------------------------------------------------------- /src/redux/components/Link.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import propType from 'prop-types' 3 | 4 | const Link = ({ active, children, onClick }) => { 5 | if (active) { 6 | return { children } 7 | } 8 | return ( 9 | { 12 | e.preventDefault() 13 | onClick() 14 | }}> 15 | {children} 16 | 17 | ) 18 | } 19 | Link.propType = { 20 | active: propType.bool.isRequired, 21 | children: propType.node.isRequired, 22 | onClick: propType.func.isRequired 23 | } 24 | 25 | export default Link -------------------------------------------------------------------------------- /src/redux-test/actions/index.js: -------------------------------------------------------------------------------- 1 | let nextTodoId = 0 2 | 3 | export const VisibilityFilters = { 4 | SHOW_ALL: 'SHOW_ALL', 5 | SHOW_COMPLETED: 'SHOW_COMPLETED', 6 | SHOW_ACTIVE: 'SHOW_ACTIVE' 7 | } 8 | 9 | // 添加 10 | export function addList (text) { 11 | return { 12 | type: 'ADD_TODO', 13 | id: nextTodoId++, 14 | text 15 | } 16 | } 17 | 18 | export function toggleTodo (index) { 19 | return { 20 | type: 'TOGGLE_TODO', 21 | index 22 | } 23 | } 24 | 25 | export function setVisibility (filter) { 26 | return { 27 | type: 'SET_VISIBILITY_FILTER', 28 | filter 29 | } 30 | } -------------------------------------------------------------------------------- /src/redux-test/reducer/todos.js: -------------------------------------------------------------------------------- 1 | 2 | // let addId = 0 3 | const todoApp = (state = [], action) => { 4 | switch (action.type) { 5 | case 'ADD_TODO': 6 | return [ 7 | ...state, 8 | { 9 | id: action.id, 10 | text: action.text, 11 | completed: false 12 | } 13 | ] 14 | case 'TOGGLE_TODO': 15 | return state.map(todo => 16 | todo.id === action.index ? { 17 | ...todo, 18 | completed: !todo.completed 19 | } : todo) 20 | default: 21 | return state 22 | } 23 | } 24 | export default todoApp -------------------------------------------------------------------------------- /src/App.js: -------------------------------------------------------------------------------- 1 | import React, { Component } from 'react'; 2 | import logo from './logo.svg'; 3 | import './App.css'; 4 | 5 | class App extends Component { 6 | render() { 7 | return ( 8 |
    9 |
    10 | logo 11 |

    Welcome to React

    12 |
    13 |

    14 | To get started, edit src/App.js and save to reload. 15 |

    16 |
    17 | ); 18 | } 19 | } 20 | 21 | export default App; 22 | -------------------------------------------------------------------------------- /src/redux/actions/index.js: -------------------------------------------------------------------------------- 1 | import http from './../../utils/http' 2 | // http.get('/search?keywords=%E6%B5%B7%E9%98%94%E5%A4%A9%E7%A9%BA').then(res => { 3 | 4 | // }) 5 | let nextTodoId = 0 6 | export const addTodo = text => { 7 | let id = nextTodoId++ 8 | console.log('id', id) 9 | return { 10 | type: 'ADD_TODO', 11 | id, 12 | text 13 | } 14 | } 15 | 16 | export const setVisibilityFilter = filter => { 17 | return { 18 | type: 'SET_VISIBILITY_FILTER', 19 | filter 20 | } 21 | } 22 | 23 | export const toggleTodo = id => { 24 | return { 25 | type: 'TOGGLE_TODO', 26 | id 27 | } 28 | } -------------------------------------------------------------------------------- /src/redux/containers/FilterLink.js: -------------------------------------------------------------------------------- 1 | import { connect } from 'react-redux' 2 | import { setVisibilityFilter } from '../actions' 3 | import Link from './../components/Link' 4 | 5 | const mapStateToProps = (state, ownProps) => { 6 | return { 7 | active: ownProps.filter === state.VisibilityFilter 8 | } 9 | } 10 | 11 | const mapDispathToProps = (dispatch, ownProps) => { 12 | return { 13 | onClick: () => { 14 | dispatch(setVisibilityFilter(ownProps.filter)) 15 | } 16 | } 17 | } 18 | 19 | const FilterLink = connect( 20 | mapStateToProps, 21 | mapDispathToProps 22 | )(Link) 23 | 24 | export default FilterLink -------------------------------------------------------------------------------- /src/liferecycle/createRef.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | class MyCreateRef extends React.Component{ 3 | constructor(props) { 4 | super(props) 5 | this.inputRef = React.createRef() 6 | } 7 | 8 | render() { 9 | return 10 | } 11 | 12 | componentDidMount () { 13 | this.inputRef.current.focus() 14 | this.inputRef.current.value = 'daiwei' 15 | } 16 | } 17 | 18 | let RefChild = React.forwardRef ((props, ref) => ( 19 | 22 | )) 23 | 24 | export { 25 | MyCreateRef, 26 | RefChild 27 | } -------------------------------------------------------------------------------- /src/redux-study/container/FilterLink.js: -------------------------------------------------------------------------------- 1 | import { connect } from 'react-redux' 2 | import { setVisibilityFilter } from './../actions/action' 3 | import Link from '../components/Link' 4 | 5 | const mapStateToProps = (state, ownProps) => { 6 | return { 7 | active: ownProps.filter === state.visibilityFilter 8 | } 9 | } 10 | 11 | const mapDisToProps = (dispatch, ownProps) => { 12 | return { 13 | onClick: () => { 14 | dispatch(setVisibilityFilter(ownProps.filter)) 15 | } 16 | } 17 | } 18 | 19 | const FilterLink = connect( 20 | mapStateToProps, 21 | mapDisToProps 22 | )(Link) 23 | 24 | export default FilterLink 25 | -------------------------------------------------------------------------------- /src/redux-test/container/LinkInfo.js: -------------------------------------------------------------------------------- 1 | import {connect} from 'react-redux' 2 | import Link from './../components/Link' 3 | import {setVisibility} from './../actions' 4 | 5 | // import VisibilityFilters from './../actions' 6 | 7 | const mapStateToProps = (state, ownprops) => { 8 | return { 9 | active: state.visibilityFilter === ownprops.filter 10 | } 11 | } 12 | 13 | const mapDispatchToProps = (dispatch, ownprops) => { 14 | return { 15 | onClick: () => { 16 | return dispatch(setVisibility(ownprops.filter)) 17 | } 18 | } 19 | } 20 | 21 | export default connect( 22 | mapStateToProps, 23 | mapDispatchToProps 24 | )(Link) 25 | -------------------------------------------------------------------------------- /src/clickcount/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | class ClickCount extends React.Component{ 3 | constructor (props) { 4 | super(props) 5 | this.state = { 6 | count: 0 7 | } 8 | } 9 | calcCount = () => { 10 | this.setState(prev => ( 11 | { 12 | count: prev.count + 1 13 | } 14 | )) 15 | } 16 | render () { 17 | return ( 18 |
    19 | 点击的数量: {this.state.count} 20 | 21 |
    22 | ) 23 | } 24 | componentDidMount () { 25 | console.log(this.props) 26 | } 27 | } 28 | 29 | export default ClickCount 30 | -------------------------------------------------------------------------------- /src/redux-study/components/Footer.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import FilterLink from './../container/FilterLink' 3 | 4 | class Footer extends React.Component{ 5 | render () { 6 | return( 7 |

    8 | show: 9 | {' '} 10 | 11 | SHOW_ALL 12 | 13 | {' , '} 14 | 15 | SHOW_COMPLETED 16 | 17 | {' , '} 18 | 19 | SHOW_ACTIVE 20 | 21 |

    22 | ) 23 | } 24 | } 25 | 26 | export default Footer -------------------------------------------------------------------------------- /src/list/comp/addList.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import {connect} from 'react-redux' 3 | import {AddList} from './../action' 4 | class AddListComp extends React.Component{ 5 | constructor(props) { 6 | super(props) 7 | } 8 | addList = () => { 9 | if (this.input.value.length > 0) { 10 | this.props.dispatch(AddList(this.input.value)) 11 | } 12 | } 13 | render () { 14 | return ( 15 |
    16 | this.input = node}/> 17 | 18 |
    19 | ) 20 | } 21 | } 22 | 23 | AddListComp = connect()(AddListComp) 24 | export default AddListComp -------------------------------------------------------------------------------- /src/redux-test/components/Link.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import PropTypes from 'prop-types' 3 | 4 | class Link extends React.Component{ 5 | render() { 6 | const { onClick, filter, active } = this.props 7 | return ( 8 | { 9 | e.preventDefault() 10 | onClick() 11 | }} 12 | style={ 13 | { 14 | color: active ? 'red' : '#333' 15 | } 16 | }> 17 | {filter} 18 | 19 | ) 20 | } 21 | } 22 | Link.propTypes = { 23 | onClick: PropTypes.func.isRequired, 24 | filter: PropTypes.string.isRequired, 25 | active: PropTypes.bool.isRequired 26 | } 27 | export default Link -------------------------------------------------------------------------------- /src/redux/components/TodoList.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import PropTypes from 'prop-types' 3 | import Todo from './Todo' 4 | 5 | const TodoList = ({ todos, onTodoClick }) => ( 6 | 11 | ) 12 | 13 | TodoList.propTypes = { 14 | todos: PropTypes.arrayOf( 15 | PropTypes.shape({ 16 | id: PropTypes.number.isRequired, 17 | completed: PropTypes.bool.isRequired, 18 | text: PropTypes.string.isRequired 19 | }).isRequired 20 | ).isRequired, 21 | onTodoClick: PropTypes.func.isRequired 22 | } 23 | 24 | export default TodoList 25 | -------------------------------------------------------------------------------- /src/redux-study/components/Link.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import PropTypes from 'prop-types' 3 | 4 | class Link extends React.Component{ 5 | render () { 6 | const {active, children, onClick} = this.props 7 | if (active) { 8 | return {children} 9 | } 10 | return ( 11 | { 13 | e.preventDefault() 14 | onClick() 15 | }}> 16 | {children} 17 | 18 | ) 19 | } 20 | } 21 | 22 | Link.propTypes = { 23 | active: PropTypes.bool.isRequired, 24 | children: PropTypes.string.isRequired, 25 | onClick: PropTypes.func.isRequired 26 | } 27 | 28 | export default Link 29 | -------------------------------------------------------------------------------- /src/immutable/index.js: -------------------------------------------------------------------------------- 1 | import Im from 'immutable' 2 | 3 | class TestIm { 4 | testList () { 5 | const emptyList = Im.List() 6 | console.log('emptyList', emptyList) 7 | 8 | const plainArray = [1, 2, 3, 4] 9 | const listFromPlainArray = Im.List(plainArray) 10 | console.log('listFromPlainArray', listFromPlainArray) 11 | 12 | const plainSet = Im.Set([1, 2, 3, 4]) 13 | const listFromPlainSet = Im.List(plainSet) 14 | console.log('listFromPlainSet', listFromPlainSet) 15 | 16 | console.log(Im.List.isList([1,2,3])) 17 | console.log(Im.List.isList(Im.List([1,2,3]))) 18 | } 19 | // 测试初始化 20 | init () { 21 | this.testList() 22 | } 23 | } 24 | 25 | export default TestIm -------------------------------------------------------------------------------- /src/redux-study/components/Todo.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import PropTypes from 'prop-types' 3 | class Todo extends React.Component{ 4 | render () { 5 | const {onClick, completed, text} = this.props 6 | return ( 7 |
  • 14 | {text} 15 |
  • 16 | ) 17 | } 18 | } 19 | 20 | Todo.propTypes = { 21 | onClick: PropTypes.func.isRequired, 22 | completed: PropTypes.bool.isRequired, 23 | text: PropTypes.string.isRequired 24 | } 25 | 26 | export default Todo 27 | -------------------------------------------------------------------------------- /src/redux-demo/count.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import { connect } from 'react-redux' 3 | class Count extends React.Component{ 4 | render(){ 5 | const {value, onIncreaseClick} = this.props 6 | return( 7 |
    8 | {value} 9 | 10 |
    11 | ) 12 | } 13 | } 14 | 15 | function mapStateToProps (state) { 16 | return { 17 | value: state.count 18 | } 19 | } 20 | 21 | function mapDispatchToProps (dispatch) { 22 | return { 23 | onIncreaseClick: () => dispatch({ type: 'increase' }) 24 | } 25 | } 26 | 27 | const App = connect( 28 | mapStateToProps, 29 | mapDispatchToProps 30 | )(Count) 31 | 32 | export default App -------------------------------------------------------------------------------- /src/async-action/reduce.js: -------------------------------------------------------------------------------- 1 | import { combineReducers } from 'redux' 2 | function fetchData (state = { 3 | isFetch: false, 4 | data: {}, 5 | error: '' 6 | }, action) { 7 | switch (action.type) { 8 | case 'FETCH_POSTS': 9 | return Object.assign({}, state, { 10 | isFetch: true 11 | }) 12 | case 'FETCH_ERROR': 13 | return Object.assign({}, state, { 14 | isFetch: false, 15 | error: action.error 16 | }) 17 | case 'FETCH_SUCCESS': 18 | return Object.assign({}, state, { 19 | isFetch: false, 20 | data: action.data 21 | }) 22 | default: 23 | return state 24 | } 25 | } 26 | 27 | const rootReduce = combineReducers({ 28 | fetchData 29 | }) 30 | export default rootReduce -------------------------------------------------------------------------------- /src/redux/containers/AddTodo.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import { connect } from 'react-redux' 3 | import { addTodo } from './../actions' 4 | 5 | let AddTodo = ({dispatch}) => { 6 | let input 7 | return ( 8 |
    9 |
    { 11 | e.preventDefault() 12 | if(!input.value.trim()){ 13 | return 14 | } 15 | dispatch(addTodo(input.value)) 16 | input.value = '' 17 | }}> 18 | { 20 | input = node 21 | }}/> 22 | 25 |
    26 |
    27 | ) 28 | } 29 | 30 | AddTodo = connect()(AddTodo) 31 | 32 | export default AddTodo -------------------------------------------------------------------------------- /src/redux-study/actions/action.js: -------------------------------------------------------------------------------- 1 | /** 2 | * action 类型 3 | */ 4 | export const ADD_TODO = 'ADD_TODO' 5 | export const TOGGLE_TODO = 'TOGGLE_TODO' 6 | export const SET_VISIBILITY_FILTER = 'SET_VISIBILITY_FILTER' 7 | 8 | /** 9 | * 其它的常量 10 | */ 11 | export const VisibilityFilters = { 12 | SHOW_ALL: 'SHOW_ALL', 13 | SHOW_COMPLETED: 'SHOW_COMPLETED', 14 | SHOW_ACTIVE: 'SHOW_ACTIVE' 15 | } 16 | 17 | /** 18 | * action 创建函数 19 | */ 20 | export function addTodo (text) { 21 | return { 22 | type: ADD_TODO, 23 | text 24 | } 25 | } 26 | 27 | export function toggleTodo (index) { 28 | return { 29 | type: TOGGLE_TODO, 30 | index 31 | } 32 | } 33 | 34 | export function setVisibilityFilter (filter) { 35 | return { 36 | type: SET_VISIBILITY_FILTER, 37 | filter 38 | } 39 | } -------------------------------------------------------------------------------- /src/redux-test/components/ListInfoDetail.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | 3 | class ListInfoDetail extends React.Component{ 4 | render () { 5 | const {onClick, todos} = this.props 6 | return ( 7 |
    8 | { 9 | todos.map(todo => { 10 | return ( 11 |
  • { 17 | e.preventDefault() 18 | onClick(todo) 19 | }}> 20 | {todo.text} 21 |
  • 22 | ) 23 | }) 24 | } 25 |
    26 | ) 27 | } 28 | } 29 | export default ListInfoDetail -------------------------------------------------------------------------------- /src/redux/reducers/todos.js: -------------------------------------------------------------------------------- 1 | import undoable, { distinctState } from 'redux-undo' 2 | const todos = (state = [], action) => { 3 | switch (action.type) { 4 | case 'ADD_TODO': 5 | return [ 6 | ...state, 7 | { 8 | id: action.id, 9 | text: action.text, 10 | completed: false 11 | } 12 | ] 13 | case 'TOGGLE_TODO': 14 | return state.map(todo => { 15 | if (todo.id === action.id) { 16 | return { 17 | ...todo, 18 | completed: !todo.completed 19 | } 20 | } else { 21 | return todo 22 | } 23 | }) 24 | default: 25 | return state 26 | } 27 | } 28 | 29 | const undoableTodos = undoable(todos, { 30 | filter: distinctState() 31 | }) 32 | 33 | export default undoableTodos -------------------------------------------------------------------------------- /src/async-action/sagas.js: -------------------------------------------------------------------------------- 1 | import { call, takeEvery, all, put} from 'redux-saga/effects' 2 | import axios from 'axios' 3 | import {fetchBingInfo} from './action' 4 | 5 | function* requestData (actions) { 6 | yield put(fetchBingInfo(actions.url)) 7 | try{ 8 | const res = yield call((url) => new Promise((resolve, reject) => { 9 | axios.get(url).then(res => { 10 | resolve(res) 11 | }).catch(err => { 12 | reject(err) 13 | }) 14 | }), actions.url) 15 | yield put({type: 'FETCH_SUCCESS', data: res.data}) 16 | } catch (e) { 17 | yield put({type: 'FETCH_ERROR', error: e}) 18 | } 19 | } 20 | 21 | function* watchRequestData () { 22 | yield takeEvery('FETCH_REQUEST', requestData) 23 | } 24 | 25 | export default function* rootSaga () { 26 | yield all([ 27 | watchRequestData() 28 | ]) 29 | } -------------------------------------------------------------------------------- /src/redux-study/container/AddTodo.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import { connect } from 'react-redux' 3 | import { addTodo } from './../actions/action' 4 | 5 | class AddTodo extends React.Component{ 6 | render () { 7 | var input 8 | let { dispatch } = this.props 9 | return ( 10 |
    11 |
    { 12 | e.preventDefault() 13 | if (!input.value.trim()) return 14 | dispatch(addTodo(input.value)) 15 | input.value = '' 16 | }}> 17 | { 18 | input = node 19 | }}/> 20 | 23 |
    24 |
    25 | ) 26 | } 27 | } 28 | 29 | AddTodo = connect()(AddTodo) 30 | export default AddTodo 31 | -------------------------------------------------------------------------------- /src/redux-study/components/TodoList.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import PropTypes from 'prop-types' 3 | import Todo from './Todo' 4 | 5 | class TodoList extends React.Component{ 6 | render () { 7 | const {todos, onTodoClick} = this.props 8 | return ( 9 | 16 | ) 17 | } 18 | } 19 | 20 | TodoList.propTypes = { 21 | todos: PropTypes.arrayOf( 22 | PropTypes.shape({ 23 | id: PropTypes.number.isRequired, 24 | completed: PropTypes.bool.isRequired, 25 | text: PropTypes.string.isRequired 26 | }).isRequired 27 | ).isRequired, 28 | onTodoClick: PropTypes.func.isRequired 29 | } 30 | 31 | export default TodoList 32 | -------------------------------------------------------------------------------- /src/async-action/Image.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import PropTypes from 'prop-types' 3 | class Image extends React.Component{ 4 | render () { 5 | const {getImageData, value} = this.props 6 | const {isFetch, error, data} = value.fetchData 7 | let img 8 | 9 | if (data && data.url) { 10 | img = 11 | } else { 12 | img =

    11111

    13 | } 14 | return ( 15 |
    16 |

    {isFetch ? '数据加载中...' : '数据加载完成!'}

    17 | 18 | { 19 | img 20 | } 21 |

    所有数据: {JSON.stringify(value)}

    22 |
    23 | ) 24 | } 25 | } 26 | Image.propTypes = { 27 | value: PropTypes.object, 28 | getImageData: PropTypes.func.isRequired 29 | } 30 | export default Image 31 | -------------------------------------------------------------------------------- /src/async-action/index.js: -------------------------------------------------------------------------------- 1 | import Image from './Image' 2 | import React from 'react' 3 | import {render} from 'react-dom' 4 | import { createStore, applyMiddleware } from 'redux' 5 | import reducer from './reduce' 6 | import rootSaga from './sagas' 7 | import createSagaMiddleware from 'redux-saga' 8 | 9 | const sagaMiddleware = createSagaMiddleware() 10 | const store = createStore( 11 | reducer, 12 | applyMiddleware(sagaMiddleware) 13 | ) 14 | sagaMiddleware.run(rootSaga) 15 | 16 | function renderDom () { 17 | render( 18 | { 19 | store.dispatch({ 20 | type: 'FETCH_REQUEST', 21 | url: 'http://www.daiwei.org/vue/server/home.php?inAjax=1&do=getImageByBingJson' 22 | }) 23 | }}/>, 24 | document.getElementById('async') 25 | ) 26 | } 27 | 28 | renderDom() 29 | store.subscribe(renderDom) -------------------------------------------------------------------------------- /src/liferecycle/dom.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | const divStyle = { 3 | color: 'red' 4 | } 5 | 6 | class TestDom extends React.Component { 7 | constructor(props) { 8 | super(props) 9 | } 10 | 11 | fromChange = (e) => { 12 | console.log(e.target.value) 13 | } 14 | 15 | clickButton = (e) => { 16 | console.log(e) 17 | } 18 | 19 | render(){ 20 | return ( 21 |
    22 |

    25 | 26 |
    27 | 28 | 29 |
    30 | 31 |
    32 | ) 33 | } 34 | } 35 | 36 | export default TestDom -------------------------------------------------------------------------------- /src/redux/selector.js: -------------------------------------------------------------------------------- 1 | import { createSelector } from 'reselect' 2 | const getVisibilityFilter = state => state.visibilityFilter 3 | const getTodos = state => state.todos 4 | 5 | export const getVisibleTodos = createSelector( 6 | [getVisibilityFilter, getTodos], 7 | (visibilityFilter, todos) => { 8 | switch (visibilityFilter) { 9 | case 'SHOW_ALL': 10 | return todos 11 | case 'SHOW_COMPLETED': 12 | return todos.filter(t => t.complete) 13 | case 'SHOW_ACTIVE': 14 | return todos.filter(t => !t.complete) 15 | default: 16 | return todos 17 | } 18 | } 19 | ) 20 | 21 | const getKeyword = state => state.keyword 22 | export const getVisibleTodosFilteredByKeyword = createSelector( 23 | [getVisibleTodos, getKeyword], 24 | (visibilitytodos, keyword) => visibilitytodos.filter( 25 | todo => todo.text.indexOf(keyword) > -1 26 | ) 27 | ) -------------------------------------------------------------------------------- /src/purecomp/index.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | // import Im from 'immutable' 3 | class CounterButton extends React.Component{ 4 | constructor(props) { 5 | super(props) 6 | this.state = { 7 | count: 1 8 | } 9 | } 10 | 11 | clickHandler = () => { 12 | this.setState((prevState, props) => ({ 13 | count: prevState.count + 1 14 | })) 15 | } 16 | 17 | shouldComponentUpdate(nextProps, nextState) { 18 | if (this.props.color !== nextProps.color) return true 19 | if (this.state.count !== nextState.count) return true 20 | return false 21 | } 22 | 23 | render() { 24 | return( 25 |
    26 | CounterButton: {this.state.count} 27 | 28 |
    29 | ) 30 | } 31 | } 32 | 33 | export { 34 | CounterButton 35 | } -------------------------------------------------------------------------------- /src/redux-test/container/ListInfo.js: -------------------------------------------------------------------------------- 1 | // 用于显示中间的数据列表内容 2 | import {connect} from 'react-redux' 3 | import {toggleTodo} from './../actions' 4 | import ListInfoDetail from './../components/ListInfoDetail' 5 | 6 | const getVisibilityTodos = (todos, filter) => { 7 | switch (filter) { 8 | case 'SHOW_COMPLETED': 9 | return todos.filter(t => t.completed) 10 | case 'SHOW_ACTIVE': 11 | return todos.filter(t => !t.completed) 12 | case 'SHOW_ALL': 13 | default: 14 | return todos 15 | } 16 | } 17 | 18 | const mapStateToProps = (state) => { 19 | return { 20 | todos: getVisibilityTodos(state.todos, state.visibilityFilter) 21 | } 22 | } 23 | 24 | const mapDispatchToProps = (dispatch) => { 25 | return { 26 | onClick: (todos) => { 27 | return dispatch(toggleTodo(todos.id)) 28 | } 29 | } 30 | } 31 | 32 | export default connect( 33 | mapStateToProps, 34 | mapDispatchToProps 35 | )(ListInfoDetail) -------------------------------------------------------------------------------- /src/todolist/todo.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | // import { render } from 'react-dom' 3 | import Search from './search' 4 | import List from './list' 5 | import PropTypes from 'prop-types' 6 | class Todo extends React.Component{ 7 | static contextTypes = { 8 | age: PropTypes.string.isRequired, 9 | name: PropTypes.string.isRequired 10 | } 11 | constructor(props){ 12 | super(props) 13 | this.state = { 14 | listInfo: [] 15 | } 16 | } 17 | setData = (data) => { 18 | alert(this.context.name) 19 | let arr = this.state.listInfo 20 | arr.push(data) 21 | this.setState ({ 22 | listInfo: arr 23 | }) 24 | } 25 | render () { 26 | return ( 27 |
    28 |

    {this.context.name}

    29 |

    {this.context.age}

    30 | 31 | 32 |
    33 | ) 34 | } 35 | } 36 | 37 | export default Todo -------------------------------------------------------------------------------- /src/context/index.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | const ThemeContext = React.createContext('ligth') 3 | 4 | class Button extends React.Component{ 5 | render() { 6 | return( 7 | 8 | ) 9 | } 10 | } 11 | 12 | class ThemeButton extends React.Component{ 13 | render() { 14 | return( 15 | 16 | {theme => 39 | 40 | ) 41 | } 42 | } 43 | export default MyRedirect -------------------------------------------------------------------------------- /src/redux/containers/UnDo.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import { ActionCreators as UndoActionCreators } from 'redux-undo' 3 | import { connect } from 'react-redux' 4 | 5 | class UnDo extends React.Component{ 6 | render () { 7 | const { canUndo, canRedo, onUndo, onRedo } = this.props 8 | return ( 9 |

    10 | 13 | 16 |

    17 | ) 18 | } 19 | } 20 | 21 | const mapStateToProps = (state) => { 22 | return { 23 | canUndo: state.todos.past.length > 0, 24 | canRedo: state.todos.future.length > 0 25 | } 26 | } 27 | 28 | const mapDispatchToProps = (dispatch) => { 29 | return { 30 | onUndo: () => dispatch(UndoActionCreators.undo()), 31 | onRedo: () => dispatch(UndoActionCreators.redo()) 32 | } 33 | } 34 | 35 | const UnDoC = connect( 36 | mapStateToProps, 37 | mapDispatchToProps 38 | )(UnDo) 39 | 40 | export default UnDoC 41 | -------------------------------------------------------------------------------- /src/noctrl/index.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | class NameForm extends React.Component{ 3 | constructor(props) { 4 | super(props) 5 | } 6 | handleClick = (e) => { 7 | e.preventDefault() 8 | alert(this.input.value) 9 | } 10 | render() { 11 | return ( 12 |
    13 | this.input = node}/> 14 | 15 |
    16 | ) 17 | } 18 | } 19 | 20 | class FileInput extends React.Component{ 21 | constructor(props) { 22 | super(props) 23 | this.state = { 24 | filetext: '' 25 | } 26 | } 27 | subFile = (e) => { 28 | e.preventDefault() 29 | this.setState({ 30 | filetext: this.input.files[0].name 31 | }) 32 | } 33 | render() { 34 | return( 35 |
    36 | this.input = file}/> 37 | 38 |

    fileText: {this.state.filetext}

    39 |
    40 | ) 41 | } 42 | } 43 | 44 | export { 45 | NameForm, 46 | FileInput 47 | } -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "react-app", 3 | "version": "0.1.0", 4 | "private": true, 5 | "homepage": ".", 6 | "dependencies": { 7 | "axios": "^0.18.0", 8 | "cross-fetch": "^2.2.3", 9 | "immutable": "^3.8.2", 10 | "react": "^16.4.1", 11 | "react-addons-css-transition-group": "^15.6.2", 12 | "react-dom": "^16.4.1", 13 | "react-redux": "^5.0.7", 14 | "react-router": "^4.3.1", 15 | "react-router-dom": "^4.3.1", 16 | "react-scripts": "1.1.4", 17 | "redux": "^4.0.0", 18 | "redux-logger": "^3.0.6", 19 | "redux-saga": "^0.16.2", 20 | "redux-thunk": "^2.3.0", 21 | "redux-undo": "^0.6.1", 22 | "reselect": "^4.0.0", 23 | "url-parse": "^1.4.3" 24 | }, 25 | "scripts": { 26 | "start": "react-scripts start", 27 | "build": "react-scripts build", 28 | "test": "react-scripts test --env=jsdom", 29 | "eject": "react-scripts eject" 30 | }, 31 | "devDependencies": { 32 | "babel-plugin-transform-class-properties": "^6.24.1", 33 | "babel-plugin-transform-decorators-legacy": "^1.3.5", 34 | "babel-preset-env": "^1.7.0" 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/renderprop/index.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | class MouseReacker extends React.Component{ 3 | constructor(props){ 4 | super(props) 5 | this.state = { 6 | x: 0, 7 | y: 0 8 | } 9 | } 10 | 11 | move = (e) => { 12 | this.setState({ 13 | x: e.pageX - e.target.offsetLeft, 14 | y: e.pageY - e.target.offsetTop 15 | }) 16 | } 17 | 18 | render () { 19 | return ( 20 |
    27 |

    just move mouse

    28 | 38 |

    The current mouse position is ({this.state.x}, {this.state.y})

    39 |
    40 | ) 41 | } 42 | } 43 | 44 | export default MouseReacker -------------------------------------------------------------------------------- /src/refs/index.jsx: -------------------------------------------------------------------------------- 1 | import React, { PureComponent } from 'react' 2 | class CustomTextInput extends React.Component{ 3 | constructor(props) { 4 | super(props) 5 | this.textInput = React.createRef() 6 | } 7 | focusTextInput = () => { 8 | this.textInput.current.focus() 9 | } 10 | render() { 11 | return( 12 |
    13 | 15 | 18 |
    19 | ) 20 | } 21 | } 22 | 23 | class Refs extends React.Component{ 24 | constructor(props){ 25 | super(props) 26 | this.myRef = React.createRef() 27 | this.refInput = React.createRef() 28 | } 29 | render(){ 30 | return ( 31 |
    32 |

    你好,React

    33 | 34 |
    35 | ) 36 | } 37 | componentDidMount(){ 38 | this.refInput.current.focusTextInput() 39 | console.log(this.myRef.current) 40 | console.log(this.refInput.current.focusTextInput()) 41 | } 42 | } 43 | export {Refs} -------------------------------------------------------------------------------- /src/redux-study/reduces/reduces.js: -------------------------------------------------------------------------------- 1 | import { combineReducers } from 'redux' 2 | import { 3 | ADD_TODO, 4 | // TOGO_TODO, 5 | SET_VISIBILITY_FILTER, 6 | VisibilityFilters, 7 | TOGGLE_TODO 8 | } from './../actions/action' 9 | 10 | const { SHOW_ALL } = VisibilityFilters 11 | 12 | function visibilityFilter (state = SHOW_ALL, action) { 13 | switch (action.type) { 14 | case SET_VISIBILITY_FILTER: 15 | return action.filter 16 | default: 17 | return state 18 | } 19 | } 20 | 21 | function todos (state = [], action) { 22 | switch (action.type) { 23 | case ADD_TODO: 24 | return [ 25 | ...state, 26 | { 27 | text: action.text, 28 | completed: false 29 | } 30 | ] 31 | case TOGGLE_TODO: 32 | return state.map((todo, index) => { 33 | if (index === action.index) { 34 | return Object.assign({}, todo, { 35 | completed: !todo.completed 36 | }) 37 | } 38 | return todo 39 | }) 40 | default: 41 | return state 42 | } 43 | } 44 | 45 | const todoApp = combineReducers({ 46 | visibilityFilter, 47 | todos 48 | }) 49 | 50 | export default todoApp 51 | -------------------------------------------------------------------------------- /src/gaojie/ele.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | // function setHeader (title) { 3 | // return function (HeaderComponents) { 4 | // return class HOC extends React.Component{ 5 | // componentWillMount () { 6 | // // alert(1) 7 | // } 8 | // render() { 9 | // return ( 10 | //
    11 | //
    12 | // { 13 | // title ? title : '这是默认的头部文字' 14 | // } 15 | //
    16 | // 17 | //
    18 | // ) 19 | // } 20 | // } 21 | // } 22 | // } 23 | // export default setHeader 24 | export default (title) => (HeaderComponents) => class HOC extends React.Component{ 25 | componentDidMount() { 26 | // 可以方便地得到state,做一些更深入的修改。 27 | console.log('setHeaderInfo', this.state); 28 | } 29 | render() { 30 | const newProps = { 31 | test:' --> | 这是高阶组件 --> 属性代理' 32 | } 33 | return ( 34 |
    35 |
    36 | { 37 | title ? title : '这是默认的名字' 38 | } 39 | 40 |
    41 |
    42 | ) 43 | } 44 | } -------------------------------------------------------------------------------- /src/render/index.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import TestRender from './testrender' 3 | class RenderForm extends React.Component{ 4 | constructor(props){ 5 | super(props) 6 | this.inputName 7 | this.age 8 | this.state = { 9 | listData: [] 10 | } 11 | } 12 | onSubmit = (e) => { 13 | e.preventDefault() 14 | if (this.inputName.value && this.age.value) { 15 | let obj = { 16 | name: this.inputName.value, 17 | age: this.age.value 18 | } 19 | this.setState((prevState) => ( 20 | { 21 | listData: [...prevState.listData, obj] 22 | } 23 | )) 24 | console.log(this.state.listData) 25 | } 26 | } 27 | render() { 28 | return( 29 |
    30 | this.inputName = node }/> 31 | this.age = node }/> 32 | 33 |
    34 | { 35 | this.state.listData.map((item, index) => ( 36 | 37 | )) 38 | } 39 |
    40 |
    41 | ) 42 | } 43 | } 44 | export default RenderForm -------------------------------------------------------------------------------- /src/transition/index.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import ReactCSSTransitionGroup from 'react-addons-css-transition-group' 3 | import './transition.css' 4 | class TodoList extends React.Component{ 5 | constructor (props) { 6 | super(props) 7 | this.state = { 8 | items: ['hello', 'world', 'click', 'me'] 9 | } 10 | } 11 | handleAdd = () => { 12 | const newItems = this.state.items.concat([ 13 | prompt('Enter some text') 14 | ]) 15 | this.setState({ 16 | items: newItems 17 | }) 18 | } 19 | handleRemove = (i) => { 20 | let newItems = this.state.items.slice() 21 | newItems.splice(i, 1) 22 | this.setState({ 23 | items: newItems 24 | }) 25 | } 26 | 27 | render () { 28 | const item = this.state.items.map((item, i) => ( 29 |
    30 | {item} 31 |
    32 | )) 33 | return ( 34 |
    35 | 38 | 44 | {item} 45 | 46 |
    47 | ) 48 | } 49 | } 50 | export default TodoList -------------------------------------------------------------------------------- /src/renderprop/comp.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | class Cat extends React.Component{ 3 | render() { 4 | const {mouse} = this.props 5 | return ( 6 |
    17 | ) 18 | } 19 | } 20 | 21 | class Mouse extends React.Component{ 22 | constructor(props) { 23 | super(props) 24 | this.state = { 25 | x: 0, 26 | y: 0 27 | } 28 | } 29 | move = (e) => { 30 | this.setState({ 31 | x: e.pageX - e.target.offsetLeft, 32 | y: e.pageY - e.target.offsetTop, 33 | }) 34 | } 35 | render() { 36 | return ( 37 |
    43 | {this.props.render(this.state)} 44 |
    45 | ) 46 | } 47 | } 48 | 49 | export default class TestRenderProp extends React.Component{ 50 | render() { 51 | return( 52 |
    53 | ( 54 | 55 | )}> 56 | 57 |
    58 | ) 59 | } 60 | } -------------------------------------------------------------------------------- /src/portals/index.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import ReactDOM from 'react-dom' 3 | // const appRoot = document.getElementById('app-root') 4 | const modalRoot = document.getElementById('modal-root') 5 | 6 | class Modal extends React.Component{ 7 | constructor (props) { 8 | super(props) 9 | this.el = document.createElement('div') 10 | } 11 | 12 | componentDidMount () { 13 | modalRoot.appendChild(this.el) 14 | } 15 | 16 | componentWillUnmount () { 17 | modalRoot.removeChild(this.el) 18 | } 19 | 20 | render () { 21 | return ReactDOM.createPortal( 22 | this.props.children, 23 | this.el 24 | ) 25 | } 26 | } 27 | 28 | class Parent extends React.Component{ 29 | constructor(props) { 30 | super(props) 31 | this.state = { 32 | count: 0 33 | } 34 | } 35 | 36 | handleClick = () => { 37 | this.setState((prevState) => ({ 38 | count: prevState.count + 1 39 | })) 40 | } 41 | 42 | render () { 43 | return ( 44 |
    47 |

    Number of Clicks: {this.state.count}

    48 |

    49 | Open up the browser DevTools 50 | to observe that the button 51 | is not a child of the div 52 | with the onClick handler. 53 |

    54 | 55 |
    56 | 57 |
    58 |
    59 |
    60 | ) 61 | } 62 | } 63 | 64 | export default Parent -------------------------------------------------------------------------------- /src/redux/containers/VisibleTodoList.js: -------------------------------------------------------------------------------- 1 | import { connect } from 'react-redux' 2 | import { toggleTodo } from '../actions' 3 | import TodoList from '../components/TodoList' 4 | import {createSelector} from 'reselect' 5 | const getVisibleTodos = (todos, filter) => { 6 | switch (filter) { 7 | case 'SHOW_COMPLETED': 8 | return todos.filter(t => t.completed) 9 | case 'SHOW_ACTIVE': 10 | return todos.filter(t => !t.completed) 11 | case 'SHOW_ALL': 12 | default: 13 | return todos 14 | } 15 | } 16 | 17 | // const getTodos = state => state.todos 18 | // const getVisibilityFilter = state => state.visibilityFilter 19 | // const getKeyword = (state) => state.keyword 20 | // const getVisibleTodos = createSelector( 21 | // getTodos, 22 | // getVisibilityFilter, 23 | // getKeyword, 24 | // (todos, visibilityFilter, keywords) => { 25 | // switch (visibilityFilter) { 26 | // case 'SHOW_COMPLETED': 27 | // return todos.filter(t => t.completed) 28 | // case 'SHOW_ACTIVE': 29 | // return todos.filter(t => !t.completed) 30 | // case 'SHOW_ALL': 31 | // default: 32 | // return todos 33 | // } 34 | // } 35 | // ) 36 | 37 | const mapStateToProps = state => { 38 | return { 39 | todos: getVisibleTodos(state.todos.present, state.visibilityFilter) 40 | } 41 | } 42 | 43 | const mapDispatchToProps = dispatch => { 44 | return { 45 | onTodoClick: id => { 46 | dispatch(toggleTodo(id)) 47 | } 48 | } 49 | } 50 | 51 | const VisibleTodoList = connect( 52 | mapStateToProps, 53 | mapDispatchToProps 54 | )(TodoList) 55 | 56 | export default VisibleTodoList 57 | -------------------------------------------------------------------------------- /src/extends/index.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | class FancyBorder extends React.Component{ 3 | render() { 4 | return( 5 |
    7 | {this.props.children} 8 |
    9 | ) 10 | } 11 | } 12 | 13 | class WelcomeDialog extends React.Component{ 14 | render () { 15 | return ( 16 | 17 |

    这是title

    18 |

    这是一个组件的内容信息哈哈哈哈哈哈哈

    19 |
    20 | ) 21 | } 22 | } 23 | 24 | class Dialog extends React.Component{ 25 | render() { 26 | return( 27 | 28 |

    {this.props.title}

    29 |

    {this.props.message}

    30 | {this.props.children} 31 |
    32 | ) 33 | } 34 | } 35 | 36 | class signUpDialog extends React.Component{ 37 | constructor(props){ 38 | super(props) 39 | this.state = { 40 | login: '' 41 | } 42 | } 43 | handleClick = (e) => { 44 | alert('welcome to react --- ' + this.state.login) 45 | } 46 | handleChange = (e) => { 47 | this.setState({ 48 | login: e.target.value 49 | }) 50 | } 51 | render() { 52 | return( 53 | 55 | 56 | 57 | 58 | ) 59 | } 60 | } 61 | 62 | export { 63 | WelcomeDialog, 64 | signUpDialog 65 | } -------------------------------------------------------------------------------- /public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 11 | 12 | 13 | 22 | React App 23 | 24 | 25 | 28 |
    29 |
    30 |
    31 | 32 |
    33 |
    34 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /src/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import { render } from 'react-dom' 3 | import Im from 'immutable' 4 | import TestIm from './immutable' 5 | import './async-action/index' 6 | 7 | // import {Provider} from 'react-redux' 8 | // import {createStore} from 'redux' 9 | // import Counter from './redux-demo/reducer' 10 | // import App from './redux-demo/count' 11 | // // import { Provider } from 'react-redux' 12 | // // import { createStore } from 'redux' 13 | // // import todoApp from './redux/reducers' 14 | // // import App from './redux/components/App' 15 | import MyRoute from './router/index' 16 | import './list' 17 | import './redux' 18 | import './async-action/index' 19 | window.Im = Im 20 | render( 21 | , 22 | document.getElementById('root') 23 | ) 24 | 25 | new TestIm().init() 26 | 27 | // let store = createStore(Counter) 28 | 29 | // render( 30 | // 31 | // 32 | // , 33 | // document.getElementById('root') 34 | // ) 35 | 36 | // =================redux-study 37 | // import React from 'react' 38 | // import { render } from 'react-dom' 39 | // import { Provider } from 'react-redux' 40 | // import { createStore } from 'redux' 41 | // import todoApp from './redux-study/reduces/reduces' 42 | // import App from './redux-study/components/App' 43 | 44 | // let store = createStore(todoApp) 45 | // render ( 46 | // 47 | // 48 | // , 49 | // document.getElementById('root') 50 | // ) 51 | 52 | // =================redux-text 53 | // import React from 'react' 54 | // import {render} from 'react-dom' 55 | // import {Provider} from 'react-redux' 56 | // import {createStore} from 'redux' 57 | // import todoApp from './redux-test/reducer' 58 | // import App from './redux-test/App' 59 | 60 | // let store = createStore(todoApp) 61 | 62 | // render( 63 | // 64 | // 65 | // , 66 | // document.getElementById('root') 67 | // ) -------------------------------------------------------------------------------- /src/context/test.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | const theme = { 3 | dark: { 4 | background: '#000', 5 | color: '#fff' 6 | }, 7 | light: { 8 | background: '#fff', 9 | color: '#000' 10 | } 11 | } 12 | const ThemeContext = React.createContext(theme.dark) 13 | 14 | class Tips extends React.Component{ 15 | constructor (props) { 16 | super(props) 17 | this.state = { 18 | style: { 19 | width: '300px', 20 | height: '150px', 21 | display: 'flex', 22 | alignItems: 'center', 23 | border: '1px solid red' 24 | } 25 | } 26 | } 27 | render() { 28 | return( 29 | 30 | { 31 | (theme, toggleTheme) => ( 32 |
    36 |

    这是用于测试context自上到下切换样式的Demo

    39 |
    40 | ) 41 | } 42 |
    43 | ) 44 | } 45 | } 46 | 47 | // 切换主题的设置 48 | class ConfigBtn extends React.Component{ 49 | constructor(props){ 50 | super(props) 51 | } 52 | 53 | handleChange = () => { 54 | this.props.changeTheme() 55 | } 56 | 57 | render() { 58 | return 59 | } 60 | } 61 | 62 | class ContextTheme extends React.Component{ 63 | constructor(props) { 64 | super(props) 65 | this.state = { 66 | theme: theme.light 67 | } 68 | } 69 | 70 | ToggleTheme = () => { 71 | this.setState(pervState => ({ 72 | theme: pervState.theme === theme.dark ? theme.light : theme.dark 73 | })) 74 | } 75 | 76 | render() { 77 | return ( 78 | 79 | 80 | 81 | 82 | ) 83 | } 84 | } 85 | 86 | export default ContextTheme -------------------------------------------------------------------------------- /src/context/test1.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | const themes = { 3 | dark: { 4 | background: '#333', 5 | color: '#fff' 6 | }, 7 | light: { 8 | background: '#fff', 9 | color: '#333' 10 | } 11 | } 12 | const ContextInfo = React.createContext({ 13 | theme: themes.dark, 14 | toggoleTheme: () => {} 15 | }) 16 | 17 | class ThemeToggleButton extends React.Component{ 18 | render() { 19 | return ( 20 | 21 | { 22 | ({theme, toggoleTheme}) => ( 23 |
    24 |
    34 |

    这是我显示内容得颜色呀呀呀呀呀

    36 |
    37 | 38 |
    39 | ) 40 | } 41 |
    42 | ) 43 | } 44 | } 45 | 46 | class ContextComp extends React.Component{ 47 | constructor(props) { 48 | super(props) 49 | this.toggoleTheme = () => { 50 | this.setState(prevState => ({ 51 | theme: prevState.theme === themes.dark ? themes.light : themes.dark, 52 | count: prevState.count + 1 53 | })) 54 | } 55 | this.state = { 56 | theme: themes.light, 57 | toggoleTheme: this.toggoleTheme, 58 | count: 0 59 | } 60 | } 61 | render() { 62 | if (this.state.count > 5) throw new Error('I crashed!'); 63 | return( 64 | 65 |
    66 | 67 |
    68 |
    69 | ) 70 | } 71 | } 72 | 73 | 74 | export default ContextComp -------------------------------------------------------------------------------- /src/gaojie/index.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import WithHeader from './test' 3 | import setHeader from './ele' 4 | import ExtendsCom from './extends' 5 | import RefsComp from './refs' 6 | import LogProps from './refs1' 7 | 8 | // @withHeader 9 | class TG extends React.Component{ 10 | render() { 11 | return ( 12 |
    13 | 我是一个普通的组件 14 |
    15 | ) 16 | } 17 | } 18 | 19 | class MTG extends React.Component{ 20 | constructor(props) { 21 | super(props) 22 | this.state = { 23 | name: '戴维' 24 | } 25 | } 26 | render() { 27 | return( 28 |
    29 | 这是组件的内容信息{this.props.test} 30 |
    31 | ) 32 | } 33 | } 34 | 35 | class ETG extends React.Component{ 36 | constructor(props) { 37 | super(props) 38 | this.state = { 39 | count: 1 40 | } 41 | } 42 | componentDidMount() { 43 | console.log('this.props.refs', this.props) 44 | } 45 | render() { 46 | const { getRef, ...props} = this.props 47 | console.log('props', ...props) 48 | console.log('this.props', this.props) 49 | return ( 50 |
    51 | hello ETG 52 |
    53 | ) 54 | } 55 | } 56 | 57 | class FButton extends React.Component{ 58 | constructor(props) { 59 | super(props) 60 | this.state = { 61 | name: "daiwei", 62 | age: 25 63 | } 64 | } 65 | changeAge = () => { 66 | this.setState({ 67 | age: Math.floor(Math.random() * 80) 68 | }) 69 | } 70 | render() { 71 | return( 72 |
    73 | 74 |
    75 | ) 76 | } 77 | } 78 | 79 | // export default TestGaoJie 80 | const TestGaoJie = WithHeader (TG) 81 | const TestMineGaoJie = setHeader ('hello world')(MTG) 82 | // const ExtendsComGaoJie = ExtendsCom ('daiwei')(ETG) 83 | const TestRefsCompGaoJie = RefsComp (ETG) 84 | 85 | const TestFButton = LogProps (FButton) 86 | export { 87 | TestGaoJie, 88 | TestMineGaoJie, 89 | // ExtendsComGaoJie, 90 | TestRefsCompGaoJie, 91 | TestFButton 92 | } -------------------------------------------------------------------------------- /src/liferecycle/index.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import TestJsx from './test' 3 | class TestLifereCycle extends React.Component{ 4 | constructor(props) { 5 | super(props) 6 | this.name = '戴维' 7 | this.state = { 8 | age: 24 9 | } 10 | } 11 | 12 | clickHandler = () => { 13 | this.setState((prevState) => ({ 14 | age: prevState.age - 1 15 | })) 16 | } 17 | // getDerivedStateFromProps (nextProps, prevState) { 18 | // console.log('getDerivedStateFromProps: ', `nextProps: ${nextProps}`, `prevState: ${prevState}`) 19 | // } 20 | componentDidMount () { 21 | console.log('componentDidMount: 在该方法里设置状态将会触发重渲。') 22 | } 23 | componentWillMount() { 24 | console.log('componentWillMount') 25 | console.log(this.props) 26 | } 27 | shouldComponentUpdate (nextProps, nextState) { 28 | console.log('shouldComponentUpdate', `nextProps: ${nextProps}`, `prevState: ${nextState}`) 29 | return !(nextState === this.state) 30 | } 31 | // getSnapshotBeforeUpdate (prevProps, prevState) { 32 | // console.log('getSnapshotBeforeUpdate:在最新的渲染输出提交给DOM前将会立即调用', `prevProps: ${prevProps}`, `prevState: ${prevState}`) 33 | // } 34 | componentDidUpdate (prevProps, prevState) { 35 | console.log('componentDidUpdate()会在更新发生后立即被调用。该方法并不会在初始化渲染时调用', `prevProps: ${prevProps}`, `prevState: ${prevState}`) 36 | } 37 | 38 | componentWillUnmount () { 39 | console.log('componentWillUnmount: 在组件被卸载和销毁之前立刻调用') 40 | } 41 | 42 | componentDidCatch(error, info) { 43 | console.log('componentDidCatch', `error: ${error}`, `info: ${info}`) 44 | } 45 | 46 | render(){ 47 | let tpl = ( 48 | 49 | 50 | 51 | ) 52 | return ( 53 |
    54 |

    55 | 我的名字叫{this.name} 56 |

    57 |

    58 | 我{this.state.age}岁了 59 |

    60 | {tpl} 61 | 62 |
    63 | ) 64 | } 65 | } 66 | 67 | TestLifereCycle.defaultProps = { 68 | color: 'red' 69 | } 70 | 71 | export default TestLifereCycle -------------------------------------------------------------------------------- /src/stateup/index.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | class BoilingVerdict extends React.Component{ 3 | render () { 4 | const { cel } = this.props 5 | if (cel >= 100) return

    水开了

    6 | return

    水并没有开

    7 | } 8 | } 9 | 10 | const toCel = (fah) => { 11 | return (fah - 32) * 5 / 9 12 | } 13 | 14 | const toFah = (cel) => { 15 | return (cel * 9 / 5) + 32 16 | } 17 | 18 | const tryConvert = (temperature, convert) => { 19 | const input = parseFloat(temperature) 20 | if (Number.isNaN(input)) { 21 | return '' 22 | } 23 | const output = convert(input) 24 | const rounded = Math.round(output * 1000) / 1000 25 | return rounded.toString() 26 | } 27 | 28 | const scaleNames = { 29 | c: '摄氏度', 30 | f: '华氏度' 31 | } 32 | 33 | class TemperatureInput extends React.Component{ 34 | constructor(props) { 35 | super(props) 36 | this.state = { 37 | temperature: '' 38 | } 39 | } 40 | handleChange = (e) => { 41 | this.props.onTemperatureChange(e.target.value) 42 | } 43 | render(){ 44 | const temperature = this.props.temperature 45 | const scale = this.props.scale 46 | return ( 47 |
    48 | 选择输入 {scaleNames[scale]} 49 | 50 |
    51 | ) 52 | } 53 | } 54 | 55 | class CalcBoiling extends React.Component{ 56 | constructor(props) { 57 | super(props) 58 | this.state = { 59 | temperature: '', 60 | scale: 'c' 61 | } 62 | } 63 | handleCelChange = (temperature) => { 64 | this.setState({ 65 | scale: 'c', 66 | temperature 67 | }) 68 | } 69 | handleFahChange = (temperature) => { 70 | this.setState({ 71 | scale: 'f', 72 | temperature 73 | }) 74 | } 75 | render() { 76 | const {scale, temperature} = this.state 77 | const cel = scale === 'f' ? tryConvert(temperature, toCel) : temperature 78 | const fah = scale === 'c' ? tryConvert(temperature, toFah) : temperature 79 | return( 80 |
    81 | 82 | 83 |
    84 | ) 85 | } 86 | } 87 | export default CalcBoiling -------------------------------------------------------------------------------- /src/logo.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /src/registerServiceWorker.js: -------------------------------------------------------------------------------- 1 | // In production, we register a service worker to serve assets from local cache. 2 | 3 | // This lets the app load faster on subsequent visits in production, and gives 4 | // it offline capabilities. However, it also means that developers (and users) 5 | // will only see deployed updates on the "N+1" visit to a page, since previously 6 | // cached resources are updated in the background. 7 | 8 | // To learn more about the benefits of this model, read https://goo.gl/KwvDNy. 9 | // This link also includes instructions on opting out of this behavior. 10 | 11 | const isLocalhost = Boolean( 12 | window.location.hostname === 'localhost' || 13 | // [::1] is the IPv6 localhost address. 14 | window.location.hostname === '[::1]' || 15 | // 127.0.0.1/8 is considered localhost for IPv4. 16 | window.location.hostname.match( 17 | /^127(?:\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}$/ 18 | ) 19 | ); 20 | 21 | export default function register() { 22 | if (process.env.NODE_ENV === 'production' && 'serviceWorker' in navigator) { 23 | // The URL constructor is available in all browsers that support SW. 24 | const publicUrl = new URL(process.env.PUBLIC_URL, window.location); 25 | if (publicUrl.origin !== window.location.origin) { 26 | // Our service worker won't work if PUBLIC_URL is on a different origin 27 | // from what our page is served on. This might happen if a CDN is used to 28 | // serve assets; see https://github.com/facebookincubator/create-react-app/issues/2374 29 | return; 30 | } 31 | 32 | window.addEventListener('load', () => { 33 | const swUrl = `${process.env.PUBLIC_URL}/service-worker.js`; 34 | 35 | if (isLocalhost) { 36 | // This is running on localhost. Lets check if a service worker still exists or not. 37 | checkValidServiceWorker(swUrl); 38 | 39 | // Add some additional logging to localhost, pointing developers to the 40 | // service worker/PWA documentation. 41 | navigator.serviceWorker.ready.then(() => { 42 | console.log( 43 | 'This web app is being served cache-first by a service ' + 44 | 'worker. To learn more, visit https://goo.gl/SC7cgQ' 45 | ); 46 | }); 47 | } else { 48 | // Is not local host. Just register service worker 49 | registerValidSW(swUrl); 50 | } 51 | }); 52 | } 53 | } 54 | 55 | function registerValidSW(swUrl) { 56 | navigator.serviceWorker 57 | .register(swUrl) 58 | .then(registration => { 59 | registration.onupdatefound = () => { 60 | const installingWorker = registration.installing; 61 | installingWorker.onstatechange = () => { 62 | if (installingWorker.state === 'installed') { 63 | if (navigator.serviceWorker.controller) { 64 | // At this point, the old content will have been purged and 65 | // the fresh content will have been added to the cache. 66 | // It's the perfect time to display a "New content is 67 | // available; please refresh." message in your web app. 68 | console.log('New content is available; please refresh.'); 69 | } else { 70 | // At this point, everything has been precached. 71 | // It's the perfect time to display a 72 | // "Content is cached for offline use." message. 73 | console.log('Content is cached for offline use.'); 74 | } 75 | } 76 | }; 77 | }; 78 | }) 79 | .catch(error => { 80 | console.error('Error during service worker registration:', error); 81 | }); 82 | } 83 | 84 | function checkValidServiceWorker(swUrl) { 85 | // Check if the service worker can be found. If it can't reload the page. 86 | fetch(swUrl) 87 | .then(response => { 88 | // Ensure service worker exists, and that we really are getting a JS file. 89 | if ( 90 | response.status === 404 || 91 | response.headers.get('content-type').indexOf('javascript') === -1 92 | ) { 93 | // No service worker found. Probably a different app. Reload the page. 94 | navigator.serviceWorker.ready.then(registration => { 95 | registration.unregister().then(() => { 96 | window.location.reload(); 97 | }); 98 | }); 99 | } else { 100 | // Service worker found. Proceed as normal. 101 | registerValidSW(swUrl); 102 | } 103 | }) 104 | .catch(() => { 105 | console.log( 106 | 'No internet connection found. App is running in offline mode.' 107 | ); 108 | }); 109 | } 110 | 111 | export function unregister() { 112 | if ('serviceWorker' in navigator) { 113 | navigator.serviceWorker.ready.then(registration => { 114 | registration.unregister(); 115 | }); 116 | } 117 | } 118 | -------------------------------------------------------------------------------- /src/router/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import {HashRouter as Router, Route, NavLink, Link} from 'react-router-dom' 3 | import Todo from './../todolist/todo' 4 | import ClickCount from './../clickcount/index' 5 | import MyRedirect from './../redirect/index' 6 | import PropTypes from 'prop-types' 7 | import TestLifereCycle from './../liferecycle' 8 | import {MyCreateRef, RefChild} from './../liferecycle/createRef' 9 | import { findDOMNode } from 'react-dom' 10 | import TestDom from './../liferecycle/dom' 11 | import RenderForm from './../render' 12 | import CalcBoiling from './../stateup' 13 | import {signUpDialog, WelcomeDialog} from './../extends' 14 | import {Refs} from './../refs' 15 | import {NameForm, FileInput} from './../noctrl' 16 | import {CounterButton} from './../purecomp' 17 | import {TestContext} from './../context' 18 | import ContextTheme from './../context/test' 19 | import NewContext from './../context/test1' 20 | import Rorttals from './../portals' 21 | import ErrorBoundary from './../boundaries' 22 | import {TestGaoJie,TestMineGaoJie, ExtendsComGaoJie, TestRefsCompGaoJie, TestFButton} from './../gaojie' 23 | import MouseReacker from './../renderprop' 24 | import TestRenderProp from './../renderprop/comp' 25 | import Trans from './../transition' 26 | import TransSider from './../transition/sider' 27 | class MyRoute extends React.Component{ 28 | constructor (props) { 29 | super(props) 30 | this.myRef = React.createRef() 31 | } 32 | /** 33 | * 基本使用方法,声明contextTypes,在函数或者render中通过this.context调用 34 | */ 35 | static childContextTypes = { 36 | name: PropTypes.string.isRequired, 37 | age: PropTypes.string.isRequired 38 | } 39 | componentDidMount () { 40 | console.log('MyRoute mounted: ') 41 | console.log(this.myRef.current) 42 | console.log('findDOMNode(this.myRef.current)', findDOMNode(this.myRef.current)) 43 | } 44 | /** 45 | * getChildContext 指定的传递给子组件的属性需要先通过 childContextTypes 来指定,不然会产生错误。 46 | */ 47 | getChildContext = () => { 48 | return { 49 | name: "daiwei hahaha", 50 | age: "19" 51 | } 52 | } 53 | getConfirmation = (message, callback) => { 54 | const allowTransition = window.confirm(message) 55 | callback(allowTransition) 56 | } 57 | render () { 58 | return( 59 |
    60 | 61 |
    62 |
      63 |
    • 64 | todo 65 |
    • 66 |
    • 67 | 首页 68 |
    • 69 |
    • 70 | redirect 71 |
    • 72 |
    • 73 | click 80 |
    • 81 |
    • 82 | life 83 |
    • 84 |
    • 85 | createRef 86 |
    • 87 |
    • 88 | dom 89 |
    • 90 |
    • 91 | render 92 |
    • 93 |
    • 94 | stateup 95 |
    • 96 |
    • 97 | extends 98 |
    • 99 |
    • 100 | extends1 101 |
    • 102 |
    • 103 | ref 104 |
    • 105 |
    • 106 | 非控制组件 107 |
    • 108 |
    • 109 | purecomp 110 |
    • 111 |
    • 112 | context 113 |
    • 114 |
    • 115 | context1 116 |
    • 117 |
    • 118 | Rorttals 119 |
    • 120 |
    • 121 | 高阶组件 122 |
    • 123 |
    • 124 | renderprop 125 |
    • 126 |
    • 127 | TestRenderProp 128 |
    • 129 |
    • 130 | trans 131 |
    • 132 |
    • 133 | transSider 134 |
    • 135 |
    136 |
    137 | 138 | 139 | 140 | }/> 141 | {/* */} 142 | ( 143 |
    144 | 145 | 146 | 点击我 147 | 148 |
    149 | )}/> 150 | 151 | }/> 152 | }/> 153 | 154 | 155 | 156 | 157 | { 158 | return( 159 |
    160 | 161 | 162 |
    163 | ) 164 | }}/> 165 | ( 166 | 167 | )} /> 168 | ( 169 |
    170 | 171 | 172 |
    173 | )} /> 174 | ( 175 | 176 | 177 | )}/> 178 | 179 | ( 180 |
    181 | , 182 | , 183 | {/* , */} 184 | , 185 | 186 |
    187 | )}/> 188 | 189 | 190 | 191 | ( 192 | 193 | )}/> 194 |
    195 |
    196 |
    197 |
    198 | ) 199 | } 200 | } 201 | 202 | export default MyRoute --------------------------------------------------------------------------------