├── .gitignore
├── anonymous-cli-metrics.json
├── learn-shopCart
├── .gitignore
├── README.md
├── package.json
├── public
│ ├── favicon.ico
│ ├── index.html
│ ├── logo192.png
│ ├── logo512.png
│ ├── manifest.json
│ └── robots.txt
├── src
│ ├── App.css
│ ├── App.js
│ ├── App.test.js
│ ├── component
│ │ └── cartSimple.js
│ ├── index.js
│ ├── logo.svg
│ ├── serviceWorker.js
│ └── setupTests.js
└── yarn.lock
├── learn
├── .gitignore
├── .vscode
│ └── settings.json
├── README.md
├── config-overrides.js
├── package-lock.json
├── package.json
├── public
│ ├── favicon.ico
│ ├── index.html
│ ├── logo192.png
│ ├── logo512.png
│ ├── manifest.json
│ └── robots.txt
├── src
│ ├── App.js
│ ├── components
│ │ ├── ButtonTest.js
│ │ ├── CommentVs.js
│ │ ├── ContextSample.js
│ │ ├── Hoc.js
│ │ ├── Hookstest.js
│ │ ├── KFormCreate.js
│ │ ├── Lifecycle.js
│ │ └── PureComponentTest.js
│ └── index.js
└── yarn.lock
├── nextjs-github
├── .babelrc
├── components
│ ├── Layout.jsx
│ └── comp.jsx
├── demo.js
├── next-create
│ ├── .gitignore
│ ├── README.md
│ ├── package.json
│ ├── pages
│ │ └── index.js
│ ├── public
│ │ ├── favicon.ico
│ │ └── zeit.svg
│ └── yarn.lock
├── next.config.js
├── package-lock.json
├── package.json
├── pages
│ ├── _app.js
│ ├── _document.js
│ ├── a.js
│ ├── index.js
│ └── test
│ │ └── b.js
├── readme.md
├── server.js
├── test
│ └── test.css
└── yarn.lock
├── react-base
├── README.md
├── anonymous-cli-metrics.json
├── package-lock.json
├── package.json
├── public
│ ├── favicon.ico
│ ├── index.html
│ ├── logo192.png
│ ├── logo512.png
│ ├── manifest.json
│ └── robots.txt
├── src
│ ├── App.css
│ ├── App.js
│ ├── App.test.js
│ ├── Button.jsx
│ ├── data.js
│ ├── index.css
│ ├── index.js
│ ├── logo.svg
│ ├── serviceWorker.js
│ └── setupTests.js
└── yarn.lock
├── react-blog
├── .gitignore
├── README.md
├── config
│ ├── env.js
│ ├── getHttpsConfig.js
│ ├── jest
│ │ ├── cssTransform.js
│ │ └── fileTransform.js
│ ├── modules.js
│ ├── paths.js
│ ├── pnpTs.js
│ ├── webpack.config.js
│ └── webpackDevServer.config.js
├── package-lock.json
├── package.json
├── public
│ ├── favicon.ico
│ ├── index.html
│ ├── logo192.png
│ ├── logo512.png
│ ├── manifest.json
│ ├── particles1.json
│ ├── particles2.json
│ └── robots.txt
├── scripts
│ ├── build.js
│ ├── start.js
│ └── test.js
├── src
│ ├── App.css
│ ├── App.js
│ ├── App.test.js
│ ├── Router
│ │ ├── admin.js
│ │ ├── index.js
│ │ └── web.js
│ ├── api
│ │ └── index.js
│ ├── assets
│ │ ├── img
│ │ │ └── avatar.jpg
│ │ └── root.css
│ ├── index.css
│ ├── index.js
│ ├── logo.svg
│ ├── pages
│ │ ├── admin
│ │ │ ├── home
│ │ │ │ └── index.js
│ │ │ ├── layout
│ │ │ │ └── index.js
│ │ │ └── login
│ │ │ │ ├── index.js
│ │ │ │ └── index.less
│ │ └── web
│ │ │ ├── about
│ │ │ ├── about.less
│ │ │ └── index.js
│ │ │ ├── archive
│ │ │ ├── index.js
│ │ │ └── index.less
│ │ │ ├── header
│ │ │ ├── index.js
│ │ │ └── index.less
│ │ │ ├── layout
│ │ │ ├── index.js
│ │ │ └── index.less
│ │ │ ├── list
│ │ │ ├── list.js
│ │ │ └── list.less
│ │ │ ├── sider
│ │ │ ├── index.js
│ │ │ └── index.less
│ │ │ └── star
│ │ │ ├── index.js
│ │ │ └── star.less
│ ├── requireLogin.js
│ ├── serviceWorker.js
│ ├── setupTests.js
│ └── utils(公共方法)
│ │ ├── index.js
│ │ └── loadable.js
└── yarn.lock
├── react-comment
├── .gitignore
├── README.md
├── package.json
├── public
│ ├── favicon.ico
│ ├── index.html
│ ├── logo192.png
│ ├── logo512.png
│ ├── manifest.json
│ └── robots.txt
├── src
│ ├── App.css
│ ├── App.js
│ ├── App.test.js
│ ├── CommentInput.jsx
│ ├── index.css
│ ├── index.js
│ ├── logo.svg
│ ├── serviceWorker.js
│ └── setupTests.js
└── yarn.lock
├── react-demo
├── LifeCycle.js
├── build
│ ├── babel.min.js
│ ├── jquery.min.js
│ ├── prop-types.js
│ ├── react-dom.development.js
│ ├── react.development.js
│ └── react.js
├── demo1
│ └── index.html
├── demo10
│ └── index.html
├── demo11
│ └── index.html
├── demo12
│ └── index.html
├── demo2
│ └── index.html
├── demo3
│ └── index.html
├── demo4
│ └── index.html
├── demo5
│ └── index.html
├── demo6
│ └── index.html
├── demo7
│ └── index.html
├── demo8
│ └── index.html
└── demo9(实现节流)
│ └── index.html
├── react-hoc
├── .gitignore
├── README.md
├── config
│ ├── env.js
│ ├── getHttpsConfig.js
│ ├── jest
│ │ ├── cssTransform.js
│ │ └── fileTransform.js
│ ├── modules.js
│ ├── paths.js
│ ├── pnpTs.js
│ ├── webpack.config.js
│ └── webpackDevServer.config.js
├── package.json
├── public
│ ├── favicon.ico
│ ├── index.html
│ ├── logo192.png
│ ├── logo512.png
│ ├── manifest.json
│ └── robots.txt
├── scripts
│ ├── build.js
│ ├── start.js
│ └── test.js
├── src
│ ├── App.css
│ ├── App.js
│ ├── App.test.js
│ ├── component
│ │ ├── example1
│ │ │ └── index.js
│ │ ├── example2
│ │ │ └── index.js
│ │ ├── example3
│ │ │ ├── OperateRefsHOC.js
│ │ │ ├── index.js
│ │ │ └── user.js
│ │ └── useRef
│ │ │ ├── Use.js
│ │ │ └── index.js
│ ├── index.css
│ ├── index.js
│ ├── logo.svg
│ ├── serviceWorker.js
│ └── setupTests.js
└── yarn.lock
├── react-hook
├── .gitignore
├── README.md
├── package.json
├── public
│ ├── favicon.ico
│ ├── index.html
│ ├── logo192.png
│ ├── logo512.png
│ ├── manifest.json
│ └── robots.txt
├── src
│ ├── App.css
│ ├── App.js
│ ├── App.test.js
│ ├── component
│ │ ├── useEffect
│ │ │ ├── index.js
│ │ │ ├── indexHook.js
│ │ │ └── makeUnmount.js
│ │ └── useState
│ │ │ ├── index.js
│ │ │ └── indexHook.js
│ ├── index.css
│ ├── index.js
│ ├── logo.svg
│ ├── serviceWorker.js
│ └── setupTests.js
└── yarn.lock
├── react-jianshu
├── .gitignore
├── README.md
├── package.json
├── public
│ ├── api
│ │ ├── detail.json
│ │ ├── home.json
│ │ ├── homeList.json
│ │ └── login.json
│ ├── favicon.ico
│ ├── index.html
│ ├── logo192.png
│ ├── logo512.png
│ ├── manifest.json
│ └── robots.txt
├── src
│ ├── App.js
│ ├── common
│ │ └── header
│ │ │ ├── index.js
│ │ │ ├── store
│ │ │ ├── actionCreator.js
│ │ │ ├── actionTypes.js
│ │ │ ├── index.js
│ │ │ └── reducer.js
│ │ │ └── style.js
│ ├── index.js
│ ├── pages
│ │ ├── detail
│ │ │ ├── index.js
│ │ │ ├── loadable.js
│ │ │ ├── store
│ │ │ │ ├── actionCreators.js
│ │ │ │ ├── constants.js
│ │ │ │ ├── index.js
│ │ │ │ └── reducer.js
│ │ │ └── style.js
│ │ ├── home
│ │ │ ├── components
│ │ │ │ ├── List.js
│ │ │ │ ├── Recommend.js
│ │ │ │ ├── Topic.js
│ │ │ │ └── Writer.js
│ │ │ ├── index.js
│ │ │ ├── store
│ │ │ │ ├── actionCreators.js
│ │ │ │ ├── constants.js
│ │ │ │ ├── index.js
│ │ │ │ └── reducer.js
│ │ │ └── style.js
│ │ ├── login
│ │ │ ├── index.js
│ │ │ ├── store
│ │ │ │ ├── actionCreators.js
│ │ │ │ ├── constants.js
│ │ │ │ ├── index.js
│ │ │ │ └── reducer.js
│ │ │ └── style.js
│ │ └── write
│ │ │ └── index.js
│ ├── static
│ │ ├── icon-font
│ │ │ ├── iconfont.eot
│ │ │ ├── iconfont.js
│ │ │ ├── iconfont.json
│ │ │ ├── iconfont.svg
│ │ │ ├── iconfont.ttf
│ │ │ ├── iconfont.woff
│ │ │ └── iconfont.woff2
│ │ └── logo.png
│ ├── store
│ │ ├── index.js
│ │ └── reducer.js
│ └── style.js
├── yarn.lock
└── 加载更多.md
├── react-react-redux
├── .gitignore
├── README.md
├── package.json
├── public
│ ├── favicon.ico
│ ├── index.html
│ ├── logo192.png
│ ├── logo512.png
│ ├── manifest.json
│ └── robots.txt
├── src
│ ├── TodoList.js
│ ├── index.js
│ └── store
│ │ ├── index.js
│ │ └── reducer.js
└── yarn.lock
├── react-redux
├── .gitignore
├── README.md
├── package-lock.json
├── package.json
├── public
│ ├── favicon.ico
│ ├── index.html
│ ├── logo192.png
│ ├── logo512.png
│ ├── manifest.json
│ └── robots.txt
├── redux 原理图.jpg
├── src
│ ├── App.css
│ ├── App.test.js
│ ├── TodoList.js
│ ├── TodoListUI.js
│ ├── assets
│ │ └── list.json
│ ├── index.css
│ ├── index.js
│ ├── logo.svg
│ ├── serviceWorker.js
│ ├── setupTests.js
│ └── store
│ │ ├── actionCreators.js
│ │ ├── actionTypes.js
│ │ ├── index.js
│ │ ├── reducer.js
│ │ └── sagas.js
└── yarn.lock
├── react-router-antd
├── README.md
├── package-lock.json
├── package.json
├── public
│ ├── favicon.ico
│ ├── index.html
│ ├── logo192.png
│ ├── logo512.png
│ ├── manifest.json
│ └── robots.txt
├── src
│ ├── App.css
│ ├── App.js
│ ├── App.test.js
│ ├── index.css
│ ├── index.js
│ ├── logo.svg
│ ├── pages
│ │ └── Layout.jsx
│ ├── serviceWorker.js
│ └── setupTests.js
└── yarn.lock
├── react-router
├── .gitignore
├── README.md
├── package-lock.json
├── package.json
├── public
│ ├── favicon.ico
│ ├── index.html
│ ├── logo192.png
│ ├── logo512.png
│ ├── manifest.json
│ └── robots.txt
├── src
│ ├── App.css
│ ├── App.js
│ ├── App.test.js
│ ├── index.css
│ ├── index.js
│ ├── logo.svg
│ ├── serviceWorker.js
│ └── setupTests.js
└── yarn.lock
├── readme.md
└── weather
├── .gitignore
├── README.md
├── config
├── env.js
├── getHttpsConfig.js
├── jest
│ ├── cssTransform.js
│ └── fileTransform.js
├── modules.js
├── paths.js
├── pnpTs.js
├── webpack.config.js
└── webpackDevServer.config.js
├── package-lock.json
├── package.json
├── public
├── city
│ ├── citylist.json
│ ├── citys.json
│ └── hotcity.json
├── favicon.ico
├── index.html
├── logo192.png
├── logo512.png
├── manifest.json
└── robots.txt
├── scripts
├── build.js
├── start.js
└── test.js
├── src
├── App.css
├── App.js
├── App.test.js
├── index.css
├── index.js
├── logo.svg
├── pages
│ ├── main
│ │ ├── component
│ │ │ ├── cloudy.js
│ │ │ └── style.js
│ │ ├── index.js
│ │ ├── loadable.js
│ │ └── style.js
│ ├── search
│ │ ├── index.js
│ │ ├── loadable.js
│ │ └── style.js
│ └── test
│ │ └── index.js
├── serviceWorker.js
├── setupTests.js
├── static
│ ├── iconfont
│ │ ├── iconfont.eot
│ │ ├── iconfont.js
│ │ ├── iconfont.json
│ │ ├── iconfont.svg
│ │ ├── iconfont.ttf
│ │ ├── iconfont.woff
│ │ └── iconfont.woff2
│ └── img
│ │ ├── 1.jpg
│ │ ├── 2.jpg
│ │ ├── 3.jpg
│ │ ├── 4.jpg
│ │ ├── 5.jpg
│ │ ├── 中雨.png
│ │ ├── 多云.png
│ │ ├── 大雨.png
│ │ ├── 小雨.png
│ │ ├── 晴.png
│ │ ├── 阴.png
│ │ ├── 阵雨.png
│ │ └── 雷阵雨.png
└── store
│ ├── actionCreators.js
│ ├── actionTypes.js
│ ├── index.js
│ └── reducer.js
└── yarn.lock
/.gitignore:
--------------------------------------------------------------------------------
1 | # Logs
2 | logs
3 | *.log
4 | npm-debug.log*
5 | yarn-debug.log*
6 | yarn-error.log*
7 |
8 | # Runtime data
9 | pids
10 | *.pid
11 | *.seed
12 | *.pid.lock
13 |
14 | # Directory for instrumented libs generated by jscoverage/JSCover
15 | lib-cov
16 |
17 | # Coverage directory used by tools like istanbul
18 | coverage
19 |
20 | # nyc test coverage
21 | .nyc_output
22 |
23 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
24 | .grunt
25 |
26 | # Bower dependency directory (https://bower.io/)
27 | bower_components
28 |
29 | # node-waf configuration
30 | .lock-wscript
31 |
32 | # Compiled binary addons (https://nodejs.org/api/addons.html)
33 | build/Release
34 |
35 | # Dependency directories
36 | node_modules/
37 | jspm_packages/
38 |
39 | # TypeScript v1 declaration files
40 | typings/
41 |
42 | # Optional npm cache directory
43 | .npm
44 |
45 | # Optional eslint cache
46 | .eslintcache
47 |
48 | # Optional REPL history
49 | .node_repl_history
50 |
51 | # Output of 'npm pack'
52 | *.tgz
53 |
54 | # Yarn Integrity file
55 | .yarn-integrity
56 |
57 | # dotenv environment variables file
58 | .env
59 |
60 | # next.js build output
61 | .next
62 |
--------------------------------------------------------------------------------
/anonymous-cli-metrics.json:
--------------------------------------------------------------------------------
1 | {"metricId":"c2f8f15e-f1da-4788-b653-df21b1638cfe","metrics":{"from":"2020-01-08T02:30:34.361Z","to":"2020-01-08T02:30:34.361Z","successfulInstalls":1,"failedInstalls":0}}
--------------------------------------------------------------------------------
/learn-shopCart/.gitignore:
--------------------------------------------------------------------------------
1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
2 |
3 | # dependencies
4 | /node_modules
5 | /.pnp
6 | .pnp.js
7 |
8 | # testing
9 | /coverage
10 |
11 | # production
12 | /build
13 |
14 | # misc
15 | .DS_Store
16 | .env.local
17 | .env.development.local
18 | .env.test.local
19 | .env.production.local
20 |
21 | npm-debug.log*
22 | yarn-debug.log*
23 | yarn-error.log*
24 |
--------------------------------------------------------------------------------
/learn-shopCart/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "learn-shopcart",
3 | "version": "0.1.0",
4 | "private": true,
5 | "dependencies": {
6 | "@testing-library/jest-dom": "^4.2.4",
7 | "@testing-library/react": "^9.3.2",
8 | "@testing-library/user-event": "^7.1.2",
9 | "react": "^16.12.0",
10 | "react-dom": "^16.12.0",
11 | "react-scripts": "3.4.0"
12 | },
13 | "scripts": {
14 | "start": "react-scripts start",
15 | "build": "react-scripts build",
16 | "test": "react-scripts test",
17 | "eject": "react-scripts eject"
18 | },
19 | "eslintConfig": {
20 | "extends": "react-app"
21 | },
22 | "browserslist": {
23 | "production": [
24 | ">0.2%",
25 | "not dead",
26 | "not op_mini all"
27 | ],
28 | "development": [
29 | "last 1 chrome version",
30 | "last 1 firefox version",
31 | "last 1 safari version"
32 | ]
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/learn-shopCart/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dmCas/React-study/19cc2c81b77f0850c1e029050b260447c849624d/learn-shopCart/public/favicon.ico
--------------------------------------------------------------------------------
/learn-shopCart/public/logo192.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dmCas/React-study/19cc2c81b77f0850c1e029050b260447c849624d/learn-shopCart/public/logo192.png
--------------------------------------------------------------------------------
/learn-shopCart/public/logo512.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dmCas/React-study/19cc2c81b77f0850c1e029050b260447c849624d/learn-shopCart/public/logo512.png
--------------------------------------------------------------------------------
/learn-shopCart/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 | "src": "logo192.png",
12 | "type": "image/png",
13 | "sizes": "192x192"
14 | },
15 | {
16 | "src": "logo512.png",
17 | "type": "image/png",
18 | "sizes": "512x512"
19 | }
20 | ],
21 | "start_url": ".",
22 | "display": "standalone",
23 | "theme_color": "#000000",
24 | "background_color": "#ffffff"
25 | }
26 |
--------------------------------------------------------------------------------
/learn-shopCart/public/robots.txt:
--------------------------------------------------------------------------------
1 | # https://www.robotstxt.org/robotstxt.html
2 | User-agent: *
3 | Disallow:
4 |
--------------------------------------------------------------------------------
/learn-shopCart/src/App.css:
--------------------------------------------------------------------------------
1 | .App {
2 | text-align: center;
3 | }
4 |
5 | .App-logo {
6 | height: 40vmin;
7 | pointer-events: none;
8 | }
9 |
10 | @media (prefers-reduced-motion: no-preference) {
11 | .App-logo {
12 | animation: App-logo-spin infinite 20s linear;
13 | }
14 | }
15 |
16 | .App-header {
17 | background-color: #282c34;
18 | min-height: 100vh;
19 | display: flex;
20 | flex-direction: column;
21 | align-items: center;
22 | justify-content: center;
23 | font-size: calc(10px + 2vmin);
24 | color: white;
25 | }
26 |
27 | .App-link {
28 | color: #61dafb;
29 | }
30 |
31 | @keyframes App-logo-spin {
32 | from {
33 | transform: rotate(0deg);
34 | }
35 | to {
36 | transform: rotate(360deg);
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/learn-shopCart/src/App.test.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { render } from '@testing-library/react';
3 | import App from './App';
4 |
5 | test('renders learn react link', () => {
6 | const { getByText } = render();
7 | const linkElement = getByText(/learn react/i);
8 | expect(linkElement).toBeInTheDocument();
9 | });
10 |
--------------------------------------------------------------------------------
/learn-shopCart/src/index.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import ReactDOM from 'react-dom';
3 | // import App from './App';
4 | import CartSimple from './component/cartSimple'
5 | import * as serviceWorker from './serviceWorker';
6 |
7 | ReactDOM.render(, document.getElementById('root'));
8 |
9 | // If you want your app to work offline and load faster, you can change
10 | // unregister() to register() below. Note this comes with some pitfalls.
11 | // Learn more about service workers: https://bit.ly/CRA-PWA
12 | serviceWorker.unregister();
13 |
--------------------------------------------------------------------------------
/learn-shopCart/src/setupTests.js:
--------------------------------------------------------------------------------
1 | // jest-dom adds custom jest matchers for asserting on DOM nodes.
2 | // allows you to do things like:
3 | // expect(element).toHaveTextContent(/react/i)
4 | // learn more: https://github.com/testing-library/jest-dom
5 | import '@testing-library/jest-dom/extend-expect';
6 |
--------------------------------------------------------------------------------
/learn/.gitignore:
--------------------------------------------------------------------------------
1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
2 |
3 | # dependencies
4 | /node_modules
5 | /.pnp
6 | .pnp.js
7 |
8 | # testing
9 | /coverage
10 |
11 | # production
12 | /build
13 |
14 | # misc
15 | .DS_Store
16 | .env.local
17 | .env.development.local
18 | .env.test.local
19 | .env.production.local
20 |
21 | npm-debug.log*
22 | yarn-debug.log*
23 | yarn-error.log*
24 |
--------------------------------------------------------------------------------
/learn/.vscode/settings.json:
--------------------------------------------------------------------------------
1 | {
2 | "javascript.implicitProjectConfig.experimentalDecorators": true
3 | }
--------------------------------------------------------------------------------
/learn/README.md:
--------------------------------------------------------------------------------
1 | ## super() 函数是用于调用父类(超类)的一个方法。
--------------------------------------------------------------------------------
/learn/config-overrides.js:
--------------------------------------------------------------------------------
1 | const { override,
2 | fixBabelImports,addBabelPlugins
3 | } = require("customize-cra");
4 |
5 |
6 | module.exports = override(
7 | // antd按需加载
8 | fixBabelImports(
9 | "import", { libraryName: "antd", libraryDirectory: "es", style: "css" }
10 | ),
11 | addBabelPlugins(
12 | ['@babel/plugin-proposal-decorators', { legacy: true }],
13 | )
14 | );
--------------------------------------------------------------------------------
/learn/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "learn",
3 | "version": "0.1.0",
4 | "private": true,
5 | "dependencies": {
6 | "@babel/plugin-proposal-decorators": "^7.7.0",
7 | "antd": "^3.12.4",
8 | "babel-plugin-import": "^1.11.0",
9 | "react": "^16.7.0",
10 | "react-app-rewired": "^2.1.5",
11 | "react-dom": "^16.7.0",
12 | "react-scripts": "2.1.3"
13 | },
14 | "babel": {
15 | "plugins": [
16 | [
17 | "@babel/plugin-proposal-decorators",
18 | {
19 | "legacy": true
20 | }
21 | ]
22 | ],
23 | "presets": [
24 | "@babel/preset-env"
25 | ]
26 | },
27 | "scripts": {
28 | "start": "react-app-rewired start",
29 | "build": "react-app-rewired build",
30 | "test": "react-app-rewired test",
31 | "eject": "react-app-rewired eject"
32 | },
33 | "eslintConfig": {
34 | "extends": "react-app"
35 | },
36 | "browserslist": [
37 | ">0.2%",
38 | "not dead",
39 | "not ie <= 11",
40 | "not op_mini all"
41 | ],
42 | "devDependencies": {
43 | "customize-cra": "^0.9.1",
44 | "less": "^3.10.3",
45 | "less-loader": "^5.0.0"
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/learn/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dmCas/React-study/19cc2c81b77f0850c1e029050b260447c849624d/learn/public/favicon.ico
--------------------------------------------------------------------------------
/learn/public/logo192.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dmCas/React-study/19cc2c81b77f0850c1e029050b260447c849624d/learn/public/logo192.png
--------------------------------------------------------------------------------
/learn/public/logo512.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dmCas/React-study/19cc2c81b77f0850c1e029050b260447c849624d/learn/public/logo512.png
--------------------------------------------------------------------------------
/learn/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 | "src": "logo192.png",
12 | "type": "image/png",
13 | "sizes": "192x192"
14 | },
15 | {
16 | "src": "logo512.png",
17 | "type": "image/png",
18 | "sizes": "512x512"
19 | }
20 | ],
21 | "start_url": ".",
22 | "display": "standalone",
23 | "theme_color": "#000000",
24 | "background_color": "#ffffff"
25 | }
26 |
--------------------------------------------------------------------------------
/learn/public/robots.txt:
--------------------------------------------------------------------------------
1 | # https://www.robotstxt.org/robotstxt.html
2 | User-agent: *
3 | Disallow:
4 |
--------------------------------------------------------------------------------
/learn/src/App.js:
--------------------------------------------------------------------------------
1 | import React,{ Component } from 'react'
2 |
3 | class App extends Component {
4 | render () { // jsx
5 | return
6 |
7 |
8 | }
9 | }
10 |
11 | export default App
--------------------------------------------------------------------------------
/learn/src/components/ButtonTest.js:
--------------------------------------------------------------------------------
1 | import React, { Component } from 'react'
2 | import Button from 'antd/lib/button'
3 | import 'antd/dist/antd.css'
4 |
5 | class ButtonTest extends Component {
6 | render () {
7 | return (
8 |
9 |
10 |
11 | )
12 | }
13 | }
14 | export default ButtonTest
--------------------------------------------------------------------------------
/learn/src/components/CommentVs.js:
--------------------------------------------------------------------------------
1 | import React,{ Component } from 'react'
2 |
3 | // 容器组件
4 | export default class CommentVs extends Component {
5 | constructor (props) {
6 | super(props)
7 | this.state = {
8 | comment: []
9 | }
10 | }
11 | componentDidMount () {
12 | setTimeout(() => {
13 | this.setState({
14 | comment: [
15 | { body: 'react is very good', author: 'facebook'},
16 | { body: 'vue is very good', author: '尤雨溪'}
17 | ]
18 | })
19 | }, 1000)
20 | }
21 | render () {
22 | return (
23 |
24 | {
25 | this.state.comment.map((item, i) => (
26 |
27 | ))
28 | }
29 |
30 | )
31 | }
32 | }
33 |
34 | // 展示组件
35 | function Comment({ data }) {
36 | return (
37 |
38 |
{data.body}
39 |
--{data.author}
40 |
41 | )
42 | }
--------------------------------------------------------------------------------
/learn/src/components/ContextSample.js:
--------------------------------------------------------------------------------
1 | // 组件跨层级的上下文通信, 可以使用context 这种模式下会有两个角色 Provide Consumer
2 | // Provide为外层组件 用来提供数据
3 | // Consumer -> 内部需要数据时用 Consumer 来读取
4 | import React , { Component } from 'react';
5 |
6 | //1. 创建上下文
7 | const Context = React.createContext()
8 |
9 | const store = {
10 | name: '恭喜你中了一等奖',
11 | sayHi() {
12 | console.log(this.name)
13 | }
14 | }
15 |
16 | const withProvider = Comp => props => (
17 |
18 |
19 |
20 |
21 | )
22 | const withConsumer = Comp => props => (
23 |
24 | {/* 必须内嵌一个函数 */}
25 | {value => }
26 |
27 | )
28 |
29 | @withConsumer
30 | //withConsumer(Inner)
31 | class Inner extends Component {
32 | render() {
33 | console.log('Inner')
34 | return (
35 | {this.props.value.name}
36 | )
37 | }
38 | }
39 |
40 | @withProvider
41 | class ContextSample extends Component {
42 | render () {
43 | console.log('ContextSample')
44 | return (
45 |
46 |
47 |
48 | )
49 | }
50 | }
51 |
52 | export default ContextSample
53 |
--------------------------------------------------------------------------------
/learn/src/components/Hoc.js:
--------------------------------------------------------------------------------
1 | import React, { Component } from 'react'
2 |
3 | // 高阶组件--链式调用
4 | const withName = Comp => {
5 | class NewComponent extends Component {
6 | componentDidMount() {
7 | console.log('do somthing')
8 | }
9 | render () {
10 | return
11 | }
12 | }
13 |
14 | return NewComponent;
15 | }
16 |
17 | const withLog = Comp => {
18 | console.log(Comp.name + '渲染了')
19 | return props =>
20 | }
21 |
22 | // // ES6装饰器简化高阶组件的写法 必须要安装@babel/plugin-proposal-decorators
23 | // @withLog // withLog(Jpsite)
24 | // @withName // withName(withLog)
25 | // @withLog
26 | class Jpsite extends Component {
27 | render () {
28 | return (
29 |
30 | {this.props.state} - {this.props.name}
31 |
32 | )
33 | }
34 | }
35 | export default withName(withLog(App)) // 链式调用
36 | // export default Jpsite
--------------------------------------------------------------------------------
/learn/src/components/Hookstest.js:
--------------------------------------------------------------------------------
1 | // Hook(钩子函数) 它可以让你在不编写 class 的情况下使用 state 内部状态以及其他的 React 特性
2 |
3 | // 使用state Hook
4 | import React, { useState, useEffect } from 'react'
5 |
6 | // class HooksTest extends Component {
7 | // constructor (props) {
8 | // super(props)
9 |
10 | // this.state = {
11 | // count: 0
12 | // }
13 | // }
14 | // }
15 |
16 | export default function HooksTest () {
17 | // useState(initalState), 接收初始状态, 返回一个状态变量和它的更新函数, 属性名可以自定义
18 | // 声明一个新的叫做 "count" 的 state 变量
19 | const [count,setCount] = useState(0)
20 |
21 | // 数据获取 设置订阅 以及手动更改React组件中的DOM -- 副作用
22 | useEffect(() => {
23 | document.title = `您点击了 ${count} 次`;
24 | })
25 | return (
26 |
27 |
You clicked {count} times
28 | {/* 调用setCount, 修改状态count */}
29 |
30 |
31 | )
32 | }
33 |
--------------------------------------------------------------------------------
/learn/src/components/Lifecycle.js:
--------------------------------------------------------------------------------
1 | import React, { Component } from 'react'
2 |
3 | class LifeCycle extends Component {
4 | constructor (props) {
5 | super(props)
6 | console.log('1. 构造函数')
7 | this.state = {
8 | msg: '来自属性传递' + props.prop
9 | }
10 | }
11 | componentWillMount () {
12 | // 此时可以访问属性和状态,可以进行api调用 但是没有办法做dom相关操作
13 | // console.log(this.state.msg)
14 | console.log('2. 组件将要挂载')
15 | }
16 | componentDidMount () {
17 | // 组件已经渲染完成, 可以进行状态更新操作
18 | console.log('3. 组件已挂载')
19 | }
20 | componentWillReceiveProps () {
21 | // 父组件传递的属性有变化, 做相应的操作
22 | console.log('4. 组件属性更新了')
23 | }
24 | shouldComponentUpdate () {
25 | // 组件是否需要更新, 返回boolean
26 | console.log('5. 组件是否需要更新?')
27 | return true
28 | }
29 | componentWillUpdate () {
30 | console.log('6. 组件将要更新')
31 | }
32 | componentDidUpdate () {
33 | console.log('7. 组件已经更新')
34 | }
35 | render () {
36 | console.log('组件渲染')
37 | return (
38 | 组件生命周期探究
39 | )
40 | }
41 | }
42 |
43 | export default class extends Component {
44 | constructor(props){
45 | super(props)
46 | this.state = {
47 | someProp: '北辰'
48 | }
49 |
50 | setTimeout (() => {
51 | this.setState({
52 | someProp: 'beichen'
53 | })
54 | }, 2000)
55 | }
56 | render () {
57 | return
58 | }
59 | }
60 |
61 |
--------------------------------------------------------------------------------
/learn/src/components/PureComponentTest.js:
--------------------------------------------------------------------------------
1 | import React, {Component, PureComponent} from 'react'
2 | // PureComponent 组件, 其实就是定制化后的 shouldComponentUpdate 的加强
3 |
4 | // shouldComponentUpdate 的加强版
5 | class PureComponentTest extends Component {
6 | constructor(props){
7 | super(props)
8 |
9 | this.state = {
10 | comment: [
11 | { body: 'react is very good', author: 'facebook'},
12 | { body: 'vue is very good', author: '尤雨溪'}
13 | ]
14 | }
15 | setTimeout (() => {
16 | this.setState({
17 | comment: [
18 | { body: 'react is very good', author: 'facebook'},
19 | { body: 'vue is very good', author: '尤雨溪'}
20 | ]
21 | })
22 | }, 2000)
23 | }
24 |
25 | render () {
26 | // console.log('render')
27 | return (
28 |
29 | {this.state.comment.map((c,i) => (
30 |
31 | ))}
32 |
33 | )
34 | }
35 | }
36 |
37 | // PureComponent节流没必要更新的时候不更新 Component只要数据源被操作就会更新
38 | // class Comment extends Component
39 | class Comment extends PureComponent {
40 | constructor(props){
41 | super(props)
42 | }
43 | // shouldComponentUpdate(nextProp) {
44 | // console.log(nextProp)
45 | // if (nextProp.data.body === this.props.data.body && nextProp.data.author === this.props.data.author) {
46 | // console.log(false)
47 | // return false
48 | // }
49 | // console.log(true)
50 | // return true
51 | // }
52 | render () {
53 | console.log('render')
54 | return (
55 |
56 |
{this.props.data.body}
57 |
--{this.props.data.author}
58 |
59 | )
60 | }
61 | }
62 |
63 | export default PureComponentTest;
64 |
--------------------------------------------------------------------------------
/nextjs-github/.babelrc:
--------------------------------------------------------------------------------
1 | // babel配置文件
2 | {
3 | "presets": ["next/babel"],
4 | "plugins": [
5 | ["import", {
6 | "libraryName": "antd"
7 | }],
8 | [
9 | "styled-components", {"ssr": true}
10 | ]
11 | ]
12 | }
--------------------------------------------------------------------------------
/nextjs-github/components/Layout.jsx:
--------------------------------------------------------------------------------
1 | import Link from 'next/link'
2 | import { Button } from 'antd'
3 |
4 | export default ({ children }) => (
5 | <>
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 | {}
14 |
15 | {children}
16 | >
17 | )
--------------------------------------------------------------------------------
/nextjs-github/components/comp.jsx:
--------------------------------------------------------------------------------
1 | export default ({ children }) =>
--------------------------------------------------------------------------------
/nextjs-github/demo.js:
--------------------------------------------------------------------------------
1 | // 启动一个后端服务
2 | const Koa = require('koa')
3 | const next = require('next')
4 | const Router = require('koa-router')
5 |
6 | const dev = process.env.NODE_ENV !== 'production'
7 | const app = next({ dev })
8 |
9 | const handle = app.getRequestHandler()
10 |
11 | // app.prepare().then(() => {
12 | // 创建koa服务
13 | const server = new Koa()
14 | const router = new Router()
15 |
16 | router.get('/test/:id', (ctx) => {
17 | // ctx.body = `request /test ${ctx.params.id}
`
18 | ctx.body = { success: true }
19 | ctx.set('Content-Type', 'application/js')
20 | })
21 |
22 | server.use(async (ctx, next) => {
23 | // const path = ctx.path
24 | // const method = ctx.method
25 | // ctx.body= `Koa Render ${method} ${path}`
26 | await next()
27 | })
28 | // server.use(async (ctx, next) => {
29 | // ctx.body= 'Koa Render2'
30 | // })
31 | // node一块的中间件...?
32 | // async await
33 | // server.use(async (ctx, next) => { // 中间件就是一个函数
34 | // await handle(ctx.req, ctx.res)
35 | // ctx.respond = false
36 | // })
37 | //router.routes()中间件
38 | server.use(router.routes())
39 |
40 | server.listen(3000, () => {
41 | console.log('koa server listening on 3000')
42 | })
43 | // })
--------------------------------------------------------------------------------
/nextjs-github/next-create/.gitignore:
--------------------------------------------------------------------------------
1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
2 |
3 | # dependencies
4 | /node_modules
5 | /.pnp
6 | .pnp.js
7 |
8 | # testing
9 | /coverage
10 |
11 | # next.js
12 | /.next/
13 | /out/
14 |
15 | # production
16 | /build
17 |
18 | # misc
19 | .DS_Store
20 | .env*
21 |
22 | # debug
23 | npm-debug.log*
24 | yarn-debug.log*
25 | yarn-error.log*
26 |
--------------------------------------------------------------------------------
/nextjs-github/next-create/README.md:
--------------------------------------------------------------------------------
1 | This is a [Next.js](https://nextjs.org/) project bootstrapped with [`create-next-app`](https://github.com/zeit/next.js/tree/canary/packages/create-next-app).
2 |
3 | ## Getting Started
4 |
5 | First, run the development server:
6 |
7 | ```bash
8 | npm run dev
9 | # or
10 | yarn dev
11 | ```
12 |
13 | Open [http://localhost:3000](http://localhost:3000) with your browser to see the result.
14 |
15 | You can start editing the page by modifying `pages/index.js`. The page auto-updates as you edit the file.
16 |
17 | ## Learn More
18 |
19 | To learn more about Next.js, take a look at the following resources:
20 |
21 | - [Next.js Documentation](https://nextjs.org/docs) - learn about Next.js features and API.
22 | - [Learn Next.js](https://nextjs.org/learn) - an interactive Next.js tutorial.
23 |
24 | You can check out [the Next.js GitHub repository](https://github.com/zeit/next.js/) - your feedback and contributions are welcome!
25 |
26 | ## Deploy on ZEIT Now
27 |
28 | The easiest way to deploy your Next.js app is to use the [ZEIT Now Platform](https://zeit.co/import?utm_medium=default-template&filter=next.js&utm_source=create-next-app&utm_campaign=create-next-app-readme) from the creators of Next.js.
29 |
30 | Check out our [Next.js deployment documentation](https://nextjs.org/docs/deployment) for more details.
31 |
--------------------------------------------------------------------------------
/nextjs-github/next-create/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "next-create",
3 | "version": "0.1.0",
4 | "private": true,
5 | "scripts": {
6 | "dev": "next dev",
7 | "build": "next build",
8 | "start": "next start"
9 | },
10 | "dependencies": {
11 | "next": "9.3.1",
12 | "react": "16.13.1",
13 | "react-dom": "16.13.1"
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/nextjs-github/next-create/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dmCas/React-study/19cc2c81b77f0850c1e029050b260447c849624d/nextjs-github/next-create/public/favicon.ico
--------------------------------------------------------------------------------
/nextjs-github/next-create/public/zeit.svg:
--------------------------------------------------------------------------------
1 |
11 |
--------------------------------------------------------------------------------
/nextjs-github/next.config.js:
--------------------------------------------------------------------------------
1 | // 配置使其能外部引入css微博华北
2 | const withCss = require('@zeit/next-css')
3 |
4 | if (typeof require !== 'undefined') {
5 | require.extensions['.css'] = (file) => {}
6 | }
7 |
8 | module.exports = withCss({})
--------------------------------------------------------------------------------
/nextjs-github/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "y",
3 | "version": "1.0.0",
4 | "description": "",
5 | "main": "index.js",
6 | "scripts": {
7 | "test": "echo \"Error: no test specified\" && exit 1",
8 | "dev": "node server.js",
9 | "build": "next build",
10 | "start": "next start"
11 | },
12 | "author": "",
13 | "license": "ISC",
14 | "dependencies": {
15 | "@zeit/next-css": "^1.0.1",
16 | "antd": "^4.0.4",
17 | "babel-plugin-import": "^1.13.0",
18 | "babel-plugin-styled-components": "^1.10.7",
19 | "koa": "^2.11.0",
20 | "koa-router": "^8.0.8",
21 | "next": "^9.3.1",
22 | "react": "^16.13.1",
23 | "react-dom": "^16.13.1",
24 | "styled-components": "^5.0.1"
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/nextjs-github/pages/_app.js:
--------------------------------------------------------------------------------
1 | import App from 'next/app'
2 |
3 | import 'antd/dist/antd.css'
4 |
5 | import Layout from '../components/Layout'
6 |
7 | class MyApp extends App {
8 |
9 | static async getInitialProps({ Component, ctx }) {
10 | console.log('app init')
11 | let pageProps
12 |
13 | if (Component.getInitialProps) {
14 | // ctx 上下文
15 | pageProps = await Component.getInitialProps(ctx)
16 | }
17 | return {
18 | pageProps
19 | }
20 | }
21 |
22 | render() {
23 | const { Component, pageProps } = this.props
24 |
25 | return(
26 |
27 |
28 |
29 | )
30 | }
31 | }
32 |
33 | export default MyApp
--------------------------------------------------------------------------------
/nextjs-github/pages/_document.js:
--------------------------------------------------------------------------------
1 | import Document, { Html, Head, Main, NextScript } from 'next/document'
2 | import { ServerStyleSheet } from 'styled-components'
3 |
4 | // HOC
5 | function withLog (Comp) {
6 | return (props) => {
7 | console.log(props)
8 | return
9 | }
10 | }
11 |
12 | class myDocument extends Document {
13 | static async getInitialProps(ctx) {
14 | const sheet = new ServerStyleSheet()
15 |
16 | const originalRenderPage = ctx.renderPage
17 |
18 | try{
19 | ctx.renderPage = () => originalRenderPage({
20 | enhanceApp: App => (props) => sheet.collectStyles(),
21 | enhanceComponent: Component => withLog(Component)
22 | })
23 | const props = await Document.getInitialProps(ctx)
24 | return {
25 | ...props,
26 | styles: <>{props.styles}{sheet.getStyleElement()}>
27 | }
28 | } finally{
29 | sheet.seal()
30 | }
31 |
32 |
33 |
34 | }
35 |
36 |
37 |
38 | render() {
39 | return (
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 | )
48 | }
49 | }
50 |
51 | export default myDocument
--------------------------------------------------------------------------------
/nextjs-github/pages/a.js:
--------------------------------------------------------------------------------
1 | import { withRouter } from 'next/router'
2 | import Link from 'next/link'
3 | import Comp from '../components/comp'
4 | import Head from 'next/head'
5 | import styled from 'styled-components'
6 |
7 | const Title = styled.h1`
8 | color: yellow;
9 | font-size:40px;
10 | `
11 | const color = '#113366'
12 |
13 | const A = ({ router, name }) => (
14 | <>
15 | This is title
16 |
17 | {router.query.id}{name}
18 |
19 |
20 |
28 | >
29 | )
30 |
31 | A.getInitialProps = async(ctx) => {
32 |
33 | const promise = new Promise((resolve, reject) => {
34 | setTimeout(() => {
35 | resolve({
36 | name: 'wn'
37 | })
38 | }, 1000)
39 | })
40 | return await promise
41 | }
42 |
43 | export default withRouter(A)
--------------------------------------------------------------------------------
/nextjs-github/pages/index.js:
--------------------------------------------------------------------------------
1 | import Link from 'next/link'
2 | import Router from 'next/router'
3 | import { Button } from 'antd'
4 |
5 | const events = [
6 | 'routeChangeStart',
7 | 'routeChangeComplete',
8 | 'routeChangeError',
9 | 'beforeHistoryChange',
10 | 'hashChangeStart',
11 | 'hashChangeComplete'
12 | ]
13 |
14 | function makeEvent(type) {
15 | return (...args) => {
16 | console.log(type, ...args)
17 | }
18 | }
19 |
20 | events.forEach(event => {
21 | Router.events.on(event, makeEvent(event))
22 | })
23 |
24 | export default () => {
25 |
26 | return (
27 | <>
28 | Index
29 | >
30 | )
31 | }
32 |
--------------------------------------------------------------------------------
/nextjs-github/pages/test/b.js:
--------------------------------------------------------------------------------
1 | import React from 'react'
2 |
3 | class MyCount extends React.Component{
4 | state = {
5 | count: 0
6 | }
7 |
8 | componentDidMount() {
9 | this.interval = setInterval(() => {
10 | this.setState({
11 | count: this.state.count + 1
12 | })
13 | }, 1000);
14 | }
15 |
16 | componentWillUnmount() {
17 | if (this.interval) {
18 | clearInterval(this.interval)
19 | }
20 | }
21 |
22 | render () {
23 | return {this.state.count}
24 | }
25 | }
26 |
27 | export default MyCount
--------------------------------------------------------------------------------
/nextjs-github/readme.md:
--------------------------------------------------------------------------------
1 | # nextjs 作为koa的中间件使用
2 |
3 | 数据接口
4 | 数据库的连接
5 | session状态
6 |
7 | # Router 钩子
8 |
9 | routeChangeStart
10 | routeChangeComplete
11 | routeChangeError
12 | beforeHistoryChange
13 | hashChangeStart
14 | hashChangeComplete
15 |
16 | # getInitialProps
17 |
18 | # Hooks 让函数组件具有类组件的能力
19 |
20 | # document css-in-js
21 | next/js自带模块 引入
22 | > import Document, { Html, Head, Main, NextScript } from 'next/document'
--------------------------------------------------------------------------------
/nextjs-github/server.js:
--------------------------------------------------------------------------------
1 | // 启动一个后端服务
2 | const Koa = require('koa')
3 | const next = require('next')
4 | const Router = require('koa-router')
5 |
6 | const dev = process.env.NODE_ENV !== 'production'
7 | const app = next({ dev })
8 |
9 | const handle = app.getRequestHandler()
10 |
11 | app.prepare().then(() => {
12 | // 创建koa服务
13 | const server = new Koa()
14 | const router = new Router()
15 |
16 | // 路由映射
17 | router.get('/a/:id', async (ctx) => {
18 | const id = ctx.params.id
19 | await handle(ctx.req, ctx.res,{
20 | pathname: '/a',
21 | query: {
22 | id
23 | }
24 | })
25 | ctx.respond = false
26 | })
27 |
28 | server.use(router.routes())
29 | // node一块的中间件...?
30 | // async await
31 | server.use(async (ctx, next) => { // 中间件就是一个函数
32 | await handle(ctx.req, ctx.res)
33 | ctx.respond = false
34 | })
35 | server.listen(3000, () => {
36 | console.log('koa server listening on 3000')
37 | })
38 | })
--------------------------------------------------------------------------------
/nextjs-github/test/test.css:
--------------------------------------------------------------------------------
1 | body{
2 | color: red;
3 | }
--------------------------------------------------------------------------------
/react-base/anonymous-cli-metrics.json:
--------------------------------------------------------------------------------
1 | {"metricId":"29cbca7f-2580-4147-9296-490899b464c1","metrics":{"from":"2020-01-08T03:37:38.079Z","to":"2020-01-08T03:37:38.079Z","successfulInstalls":1,"failedInstalls":0}}
--------------------------------------------------------------------------------
/react-base/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "react-base",
3 | "version": "0.1.0",
4 | "private": true,
5 | "dependencies": {
6 | "@tensorflow/tfjs-vis": "^1.3.0",
7 | "@testing-library/jest-dom": "^4.2.4",
8 | "@testing-library/react": "^9.3.2",
9 | "@testing-library/user-event": "^7.1.2",
10 | "react": "^16.12.0",
11 | "react-dom": "^16.12.0",
12 | "react-scripts": "3.3.0"
13 | },
14 | "scripts": {
15 | "start": "react-scripts start",
16 | "build": "react-scripts build",
17 | "test": "react-scripts test",
18 | "eject": "react-scripts eject"
19 | },
20 | "eslintConfig": {
21 | "extends": "react-app"
22 | },
23 | "browserslist": {
24 | "production": [
25 | ">0.2%",
26 | "not dead",
27 | "not op_mini all"
28 | ],
29 | "development": [
30 | "last 1 chrome version",
31 | "last 1 firefox version",
32 | "last 1 safari version"
33 | ]
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/react-base/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dmCas/React-study/19cc2c81b77f0850c1e029050b260447c849624d/react-base/public/favicon.ico
--------------------------------------------------------------------------------
/react-base/public/logo192.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dmCas/React-study/19cc2c81b77f0850c1e029050b260447c849624d/react-base/public/logo192.png
--------------------------------------------------------------------------------
/react-base/public/logo512.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dmCas/React-study/19cc2c81b77f0850c1e029050b260447c849624d/react-base/public/logo512.png
--------------------------------------------------------------------------------
/react-base/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 | "src": "logo192.png",
12 | "type": "image/png",
13 | "sizes": "192x192"
14 | },
15 | {
16 | "src": "logo512.png",
17 | "type": "image/png",
18 | "sizes": "512x512"
19 | }
20 | ],
21 | "start_url": ".",
22 | "display": "standalone",
23 | "theme_color": "#000000",
24 | "background_color": "#ffffff"
25 | }
26 |
--------------------------------------------------------------------------------
/react-base/public/robots.txt:
--------------------------------------------------------------------------------
1 | # https://www.robotstxt.org/robotstxt.html
2 | User-agent: *
3 |
--------------------------------------------------------------------------------
/react-base/src/App.css:
--------------------------------------------------------------------------------
1 | .App {
2 | text-align: center;
3 | }
4 | .primary-class{
5 | color: #61dafb;
6 | }
7 | .App-logo {
8 | height: 40vmin;
9 | pointer-events: none;
10 | }
11 |
12 | @media (prefers-reduced-motion: no-preference) {
13 | .App-logo {
14 | animation: App-logo-spin infinite 20s linear;
15 | }
16 | }
17 |
18 | .App-header {
19 | background-color: #282c34;
20 | min-height: 100vh;
21 | display: flex;
22 | flex-direction: column;
23 | align-items: center;
24 | justify-content: center;
25 | font-size: calc(10px + 2vmin);
26 | color: white;
27 | }
28 |
29 | .App-link {
30 | color: #61dafb;
31 | }
32 |
33 | @keyframes App-logo-spin {
34 | from {
35 | transform: rotate(0deg);
36 | }
37 | to {
38 | transform: rotate(360deg);
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/react-base/src/App.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import logo from './logo.svg';
3 | import Button from './Button'
4 | import './App.css';
5 |
6 | function App() {
7 | let person = [{age: 16, name: '江军'}, {age:19, name:'Biec'}]
8 | // age > 18
9 | // find 声明式
10 | let p = person.find(p => p.age > 18)
11 | //命令式
12 | for(let pp of person){
13 | if(pp.age > 17){
14 | console.log(pp.name)
15 | }
16 | }
17 | let ages = person.map(p => PageTransitionEvent.age)
18 |
19 | let arr = [0, 1, 2]
20 |
21 | function receiveFromButton(d) {
22 | console.log('从子组件:', d);
23 | }
24 | return (
25 |
26 | {/*
*/}
27 |
29 | {
30 | arr
31 | }
32 | {
33 | person.map((p,i)=>{
34 | return
{p.name}-{p.age}
35 | })
36 | }
37 | {
38 | person.length > 3 ?
有三个人
:
小于三个人
39 | }
40 | {person.length === 2 &&
有两个人
}
41 |
55 |
56 | );
57 | }
58 |
59 | export default App;
60 |
--------------------------------------------------------------------------------
/react-base/src/App.test.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { render } from '@testing-library/react';
3 | import App from './App';
4 |
5 | test('renders learn react link', () => {
6 | const { getByText } = render();
7 | const linkElement = getByText(/learn react/i);
8 | expect(linkElement).toBeInTheDocument();
9 | });
10 |
--------------------------------------------------------------------------------
/react-base/src/Button.jsx:
--------------------------------------------------------------------------------
1 | import React from 'react'
2 |
3 | function Button(props) {
4 | let date = new Date().getTime();
5 | // 通知父组件
6 | const handleClick = () => {
7 | console.log(1234);
8 | }
9 | const { type, children, receiveFromButton } = props;
10 | //父传递一个回调函数过来, 子组件通过参数通知父组件
11 | receiveFromButton(date);
12 | return (
13 |
14 | )
15 | }
16 | export default Button;
--------------------------------------------------------------------------------
/react-base/src/data.js:
--------------------------------------------------------------------------------
1 | export function getData(nums) {
2 | let point = [];
3 | function generate() {
4 | for (let i = 0 ; i < 200; i ++) {
5 | let x = normalRandom()
6 | let y = normalRandom()
7 | point({x, y})
8 | }
9 | }
10 | // 黄点
11 | generate();
12 | // 蓝点
13 | generate();
14 | return point;
15 |
16 | }
17 |
18 | function normalRandom() {
19 | let u1 = Math.random();
20 | let u2 = Math.random();
21 | let result = Math.sqrt(-2 * Math.log(u1)) * Math.cos(2 * Math.PI * u2)
22 | return result
23 | }
24 |
--------------------------------------------------------------------------------
/react-base/src/index.css:
--------------------------------------------------------------------------------
1 | body {
2 | margin: 0;
3 | font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen',
4 | 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue',
5 | sans-serif;
6 | -webkit-font-smoothing: antialiased;
7 | -moz-osx-font-smoothing: grayscale;
8 | }
9 |
10 | code {
11 | font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New',
12 | monospace;
13 | }
14 |
--------------------------------------------------------------------------------
/react-base/src/index.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import ReactDOM from 'react-dom';
3 | import './index.css';
4 | import App from './App';
5 | import * as serviceWorker from './serviceWorker';
6 | import * as tf from '@tensorflow/tfjs'
7 | import * as tfvis from '@tensorflow/tfjs-vis'
8 |
9 |
10 | import {
11 | getData
12 | } from './data.js'
13 |
14 | window.onload = async () => {
15 | const data = getData()
16 | console.log(data)
17 | tfvis.render.scatterplot(
18 | {name: '数据'}
19 | )
20 | }
21 | //浏览器专用的 Dom
22 | ReactDOM.render(, document.getElementById('root'));
23 |
24 | // react-native
25 | // ReactNative.render()
26 | // 核心的包: react
27 | // 平台相关的包: react-dom / react native / react-TV
28 |
29 | // If you want your app to work offline and load faster, you can change
30 | // unregister() to register() below. Note this comes with some pitfalls.
31 | // Learn more about service workers: https://bit.ly/CRA-PWA
32 | serviceWorker.unregister();
33 |
--------------------------------------------------------------------------------
/react-base/src/setupTests.js:
--------------------------------------------------------------------------------
1 | // jest-dom adds custom jest matchers for asserting on DOM nodes.
2 | // allows you to do things like:
3 | // expect(element).toHaveTextContent(/react/i)
4 | // learn more: https://github.com/testing-library/jest-dom
5 | import '@testing-library/jest-dom/extend-expect';
6 |
--------------------------------------------------------------------------------
/react-blog/.gitignore:
--------------------------------------------------------------------------------
1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
2 |
3 | # dependencies
4 | /node_modules
5 | /.pnp
6 | .pnp.js
7 |
8 | # testing
9 | /coverage
10 |
11 | # production
12 | /build
13 |
14 | # misc
15 | .DS_Store
16 | .env.local
17 | .env.development.local
18 | .env.test.local
19 | .env.production.local
20 |
21 | npm-debug.log*
22 | yarn-debug.log*
23 | yarn-error.log*
24 |
--------------------------------------------------------------------------------
/react-blog/config/jest/cssTransform.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | // This is a custom Jest transformer turning style imports into empty objects.
4 | // http://facebook.github.io/jest/docs/en/webpack.html
5 |
6 | module.exports = {
7 | process() {
8 | return 'module.exports = {};';
9 | },
10 | getCacheKey() {
11 | // The output is always the same.
12 | return 'cssTransform';
13 | },
14 | };
15 |
--------------------------------------------------------------------------------
/react-blog/config/jest/fileTransform.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | const path = require('path');
4 | const camelcase = require('camelcase');
5 |
6 | // This is a custom Jest transformer turning file imports into filenames.
7 | // http://facebook.github.io/jest/docs/en/webpack.html
8 |
9 | module.exports = {
10 | process(src, filename) {
11 | const assetFilename = JSON.stringify(path.basename(filename));
12 |
13 | if (filename.match(/\.svg$/)) {
14 | // Based on how SVGR generates a component name:
15 | // https://github.com/smooth-code/svgr/blob/01b194cf967347d43d4cbe6b434404731b87cf27/packages/core/src/state.js#L6
16 | const pascalCaseFilename = camelcase(path.parse(filename).name, {
17 | pascalCase: true,
18 | });
19 | const componentName = `Svg${pascalCaseFilename}`;
20 | return `const React = require('react');
21 | module.exports = {
22 | __esModule: true,
23 | default: ${assetFilename},
24 | ReactComponent: React.forwardRef(function ${componentName}(props, ref) {
25 | return {
26 | $$typeof: Symbol.for('react.element'),
27 | type: 'svg',
28 | ref: ref,
29 | key: null,
30 | props: Object.assign({}, props, {
31 | children: ${assetFilename}
32 | })
33 | };
34 | }),
35 | };`;
36 | }
37 |
38 | return `module.exports = ${assetFilename};`;
39 | },
40 | };
41 |
--------------------------------------------------------------------------------
/react-blog/config/pnpTs.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | const { resolveModuleName } = require('ts-pnp');
4 |
5 | exports.resolveModuleName = (
6 | typescript,
7 | moduleName,
8 | containingFile,
9 | compilerOptions,
10 | resolutionHost
11 | ) => {
12 | return resolveModuleName(
13 | moduleName,
14 | containingFile,
15 | compilerOptions,
16 | resolutionHost,
17 | typescript.resolveModuleName
18 | );
19 | };
20 |
21 | exports.resolveTypeReferenceDirective = (
22 | typescript,
23 | moduleName,
24 | containingFile,
25 | compilerOptions,
26 | resolutionHost
27 | ) => {
28 | return resolveModuleName(
29 | moduleName,
30 | containingFile,
31 | compilerOptions,
32 | resolutionHost,
33 | typescript.resolveTypeReferenceDirective
34 | );
35 | };
36 |
--------------------------------------------------------------------------------
/react-blog/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dmCas/React-study/19cc2c81b77f0850c1e029050b260447c849624d/react-blog/public/favicon.ico
--------------------------------------------------------------------------------
/react-blog/public/logo192.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dmCas/React-study/19cc2c81b77f0850c1e029050b260447c849624d/react-blog/public/logo192.png
--------------------------------------------------------------------------------
/react-blog/public/logo512.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dmCas/React-study/19cc2c81b77f0850c1e029050b260447c849624d/react-blog/public/logo512.png
--------------------------------------------------------------------------------
/react-blog/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 | "src": "logo192.png",
12 | "type": "image/png",
13 | "sizes": "192x192"
14 | },
15 | {
16 | "src": "logo512.png",
17 | "type": "image/png",
18 | "sizes": "512x512"
19 | }
20 | ],
21 | "start_url": ".",
22 | "display": "standalone",
23 | "theme_color": "#000000",
24 | "background_color": "#ffffff"
25 | }
26 |
--------------------------------------------------------------------------------
/react-blog/public/particles2.json:
--------------------------------------------------------------------------------
1 | {
2 | "particles": {
3 | "number": {
4 | "value": 160,
5 | "density": {
6 | "enable": false
7 | }
8 | },
9 | "size": {
10 | "value": 3,
11 | "random": true,
12 | "anim": {
13 | "speed": 4,
14 | "size_min": 0.3
15 | }
16 | },
17 | "line_linked": {
18 | "enable": false
19 | },
20 | "move": {
21 | "random": true,
22 | "speed": 1,
23 | "direction": "top",
24 | "out_mode": "out"
25 | }
26 | },
27 | "interactivity": {
28 | "events": {
29 | "onhover": {
30 | "enable": true,
31 | "mode": "bubble"
32 | },
33 | "onclick": {
34 | "enable": true,
35 | "mode": "repulse"
36 | }
37 | },
38 | "modes": {
39 | "bubble": {
40 | "distance": 250,
41 | "duration": 2,
42 | "size": 0,
43 | "opacity": 0
44 | },
45 | "repulse": {
46 | "distance": 400,
47 | "duration": 4
48 | }
49 | }
50 | },
51 | "retina_detect": true
52 | }
53 |
--------------------------------------------------------------------------------
/react-blog/public/robots.txt:
--------------------------------------------------------------------------------
1 | # https://www.robotstxt.org/robotstxt.html
2 | User-agent: *
3 | Disallow:
4 |
--------------------------------------------------------------------------------
/react-blog/scripts/test.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | // Do this as the first thing so that any code reading it knows the right env.
4 | process.env.BABEL_ENV = 'test';
5 | process.env.NODE_ENV = 'test';
6 | process.env.PUBLIC_URL = '';
7 |
8 | // Makes the script crash on unhandled rejections instead of silently
9 | // ignoring them. In the future, promise rejections that are not handled will
10 | // terminate the Node.js process with a non-zero exit code.
11 | process.on('unhandledRejection', err => {
12 | throw err;
13 | });
14 |
15 | // Ensure environment variables are read.
16 | require('../config/env');
17 |
18 |
19 | const jest = require('jest');
20 | const execSync = require('child_process').execSync;
21 | let argv = process.argv.slice(2);
22 |
23 | function isInGitRepository() {
24 | try {
25 | execSync('git rev-parse --is-inside-work-tree', { stdio: 'ignore' });
26 | return true;
27 | } catch (e) {
28 | return false;
29 | }
30 | }
31 |
32 | function isInMercurialRepository() {
33 | try {
34 | execSync('hg --cwd . root', { stdio: 'ignore' });
35 | return true;
36 | } catch (e) {
37 | return false;
38 | }
39 | }
40 |
41 | // Watch unless on CI or explicitly running all tests
42 | if (
43 | !process.env.CI &&
44 | argv.indexOf('--watchAll') === -1 &&
45 | argv.indexOf('--watchAll=false') === -1
46 | ) {
47 | // https://github.com/facebook/create-react-app/issues/5210
48 | const hasSourceControl = isInGitRepository() || isInMercurialRepository();
49 | argv.push(hasSourceControl ? '--watch' : '--watchAll');
50 | }
51 |
52 |
53 | jest.run(argv);
54 |
--------------------------------------------------------------------------------
/react-blog/src/App.css:
--------------------------------------------------------------------------------
1 | .App {
2 | text-align: center;
3 | }
4 |
5 | .App-logo {
6 | height: 40vmin;
7 | pointer-events: none;
8 | }
9 |
10 | @media (prefers-reduced-motion: no-preference) {
11 | .App-logo {
12 | animation: App-logo-spin infinite 20s linear;
13 | }
14 | }
15 |
16 | .App-header {
17 | background-color: #282c34;
18 | min-height: 100vh;
19 | display: flex;
20 | flex-direction: column;
21 | align-items: center;
22 | justify-content: center;
23 | font-size: calc(10px + 2vmin);
24 | color: white;
25 | }
26 |
27 | .App-link {
28 | color: #61dafb;
29 | }
30 |
31 | @keyframes App-logo-spin {
32 | from {
33 | transform: rotate(0deg);
34 | }
35 | to {
36 | transform: rotate(360deg);
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/react-blog/src/App.js:
--------------------------------------------------------------------------------
1 | import React, { Component } from 'react'
2 | import { BrowserRouter as Router , Route, Link, Redirect } from 'react-router-dom'
3 | import Login from './pages/admin/login'
4 | import routes from './Router'
5 | import requireLogin from './requireLogin'
6 |
7 | class App extends Component {
8 | constructor(props){
9 | super(props)
10 | }
11 |
12 | //Redirect 路由重定向
13 | render () {
14 | return (
15 |
16 |
17 | } />
18 |
19 | {
20 | routes.map((route, i) => (
21 |
24 | ))
25 | }
26 |
27 |
28 | )
29 | }
30 | }
31 |
32 | export default App
--------------------------------------------------------------------------------
/react-blog/src/App.test.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { render } from '@testing-library/react';
3 | import App from './App';
4 |
5 | test('renders learn react link', () => {
6 | const { getByText } = render();
7 | const linkElement = getByText(/learn react/i);
8 | expect(linkElement).toBeInTheDocument();
9 | });
10 |
--------------------------------------------------------------------------------
/react-blog/src/Router/admin.js:
--------------------------------------------------------------------------------
1 | import loadable from '../utils(公共方法)/loadable'
2 |
3 | const Home = loadable(() => import('../pages/admin/home'))
4 |
5 | const routes = [
6 | {
7 | menu: true,
8 | icon: 'home',
9 | title: '首页',
10 | path: '/admin/page',
11 | component: Home
12 | }
13 | ]
14 |
15 | export default routes
--------------------------------------------------------------------------------
/react-blog/src/Router/index.js:
--------------------------------------------------------------------------------
1 | import loadable from '../utils(公共方法)/loadable'
2 |
3 | const adminLayout = loadable(() => import('../pages/admin/layout'))
4 | const webLayout = loadable(() => import('../pages/web/layout'))
5 |
6 | const routes = [
7 | {
8 | path: '/admin',
9 | component: adminLayout
10 | },
11 | {
12 | path: '/web',
13 | component: webLayout
14 | }
15 | ]
16 |
17 | export default routes
--------------------------------------------------------------------------------
/react-blog/src/Router/web.js:
--------------------------------------------------------------------------------
1 | import loadable from '../utils(公共方法)/loadable'
2 | import { HomeOutlined,EditOutlined, StarOutlined, TeamOutlined } from '@ant-design/icons';
3 | const List = loadable(() => import('../pages/web/list/list'))
4 | const Archive = loadable(() => import('../pages/web/archive'))
5 | const Star = loadable(() => import('../pages/web/star'))
6 | const About = loadable(() => import('../pages/web/about'))
7 |
8 | const webRoutes = [
9 | {
10 | menu: true,
11 | icon: HomeOutlined,
12 | title: '首页',
13 | path: '/web/index',
14 | component: List
15 | },
16 | {
17 | menu: true,
18 | icon: EditOutlined,
19 | title: '归档',
20 | path: '/web/achieve',
21 | component: Archive
22 | },
23 | {
24 | menu: true,
25 | icon: StarOutlined,
26 | title: '收藏',
27 | path: '/web/star',
28 | component: Star
29 | },
30 | {
31 | menu: true,
32 | icon: StarOutlined,
33 | title: '关于',
34 | path: '/web/about',
35 | component: About
36 | }
37 | ]
38 |
39 | export default webRoutes
--------------------------------------------------------------------------------
/react-blog/src/api/index.js:
--------------------------------------------------------------------------------
1 | import axios from 'axios'
2 | import { message } from 'antd'
3 |
4 | //如果5s内没有请求回来数据则掐断
5 | axios.default.timeout = 5000
6 |
7 | // axios.default.baseUrl = 'http://xiangxi.red/api'
8 |
9 | // http request 拦截器
10 | axios.interceptors.request.use(
11 | config => {
12 | config.headers = {
13 |
14 | }
15 | return config
16 | },
17 | error => {
18 | message.error('请求出错了,请稍后重试')
19 | return Promise.reject(error)
20 | }
21 | )
22 |
23 | // http response 拦截器
24 | axios.interceptors.response.use(
25 | res => {
26 | return res
27 | },
28 | error => {
29 | message.error('请求出错了,请稍后重试')
30 | return Promise.reject(error)
31 | }
32 | )
33 |
34 | export default {
35 | get (url, params = {}) {
36 | return new Promise((resolve, reject) => {
37 | axios.get(url, {
38 | params
39 | })
40 | .then(res =>{
41 | resolve(res.data)
42 | })
43 | })
44 | },
45 | post (url, data = {}) {
46 | return new Promise((resolve, reject) => {
47 | axios.get(url, data)
48 | .then(res =>{
49 | resolve(res.data)
50 | })
51 | })
52 | }
53 | }
--------------------------------------------------------------------------------
/react-blog/src/assets/img/avatar.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dmCas/React-study/19cc2c81b77f0850c1e029050b260447c849624d/react-blog/src/assets/img/avatar.jpg
--------------------------------------------------------------------------------
/react-blog/src/assets/root.css:
--------------------------------------------------------------------------------
1 | * {
2 | padding: 0px;
3 | margin: 0px;
4 | }
5 | .mr10 {
6 | margin-right: 10px;
7 | }
8 | .mr20 {
9 | margin-right: 20px;
10 | }
11 | .mr30 {
12 | margin-right: 30px;
13 | }
14 | .ml10 {
15 | margin-left: 10px;
16 | }
17 | .ml20 {
18 | margin-left: 20px;
19 | }
20 | .ml30 {
21 | margin-left: 30px;
22 | }
23 | .mb10 {
24 | margin-bottom: 10px;
25 | }
26 | .mb20 {
27 | margin-bottom: 20px;
28 | }
29 | .mb30 {
30 | margin-bottom: 30px;
31 | }
32 | .mt10 {
33 | margin-top: 10px;
34 | }
35 | .mt20 {
36 | margin-top: 20px;
37 | }
38 | .mt30 {
39 | margin-top: 30px;
40 | }
41 | /*
42 | 重置样式
43 | */
--------------------------------------------------------------------------------
/react-blog/src/index.css:
--------------------------------------------------------------------------------
1 | body {
2 | margin: 0;
3 | font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen',
4 | 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue',
5 | sans-serif;
6 | -webkit-font-smoothing: antialiased;
7 | -moz-osx-font-smoothing: grayscale;
8 | }
9 |
10 | code {
11 | font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New',
12 | monospace;
13 | }
14 |
--------------------------------------------------------------------------------
/react-blog/src/index.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import ReactDOM from 'react-dom';
3 | import './index.css';
4 | import 'antd/dist/antd.css'
5 | import App from './App';
6 | import * as serviceWorker from './serviceWorker';
7 |
8 | ReactDOM.render(, document.getElementById('root'));
9 |
10 | // If you want your app to work offline and load faster, you can change
11 | // unregister() to register() below. Note this comes with some pitfalls.
12 | // Learn more about service workers: https://bit.ly/CRA-PWA
13 | serviceWorker.unregister();
14 |
--------------------------------------------------------------------------------
/react-blog/src/pages/admin/home/index.js:
--------------------------------------------------------------------------------
1 | import React, { Component } from 'react'
2 |
3 | class Home extends Component {
4 | render () {
5 | return (
6 | 我是首页组件
7 | )
8 | }
9 | }
10 | export default Home
--------------------------------------------------------------------------------
/react-blog/src/pages/admin/layout/index.js:
--------------------------------------------------------------------------------
1 | import React, { Component } from 'react'
2 |
3 | class Layout extends Component {
4 | render () {
5 | return (
6 | Hello Layout
7 | )
8 | }
9 | }
10 | export default Layout
--------------------------------------------------------------------------------
/react-blog/src/pages/admin/login/index.less:
--------------------------------------------------------------------------------
1 | .login{
2 | width: 99vw;
3 | height: 99vh;
4 | position: relative;
5 | &-form{
6 | position: absolute;
7 | left: 50%;
8 | top: 50%;
9 | transform: translate(-50%,-100%);
10 | }
11 | }
--------------------------------------------------------------------------------
/react-blog/src/pages/web/about/about.less:
--------------------------------------------------------------------------------
1 | .about {
2 | .about-list {
3 | &,
4 | ul {
5 | list-style: circle;
6 | margin-left: 20px;
7 | li {
8 | margin-top: 6px;
9 | }
10 | }
11 | }
12 | .icon-email {
13 | margin-right: 6px;
14 | vertical-align: middle;
15 | }
16 | @keyframes me {
17 | 0% {
18 | background: yellow;
19 | }
20 | 100% {
21 | background: pink;
22 | }
23 | }
24 | @-webkit-keyframes me {
25 | 0% {
26 | background: yellow;
27 | }
28 | 100% {
29 | background: pink;
30 | }
31 | }
32 | .code {
33 | width: 70px;
34 | position: relative;
35 | animation: me 3s infinite ease-in-out alternate;
36 | }
37 | .link {
38 | position: relative;
39 | text-decoration: none;
40 | color: #121314;
41 | &:after {
42 | content: "";
43 | position: absolute;
44 | top: 60%;
45 | left: -0.1em;
46 | right: -0.1em;
47 | bottom: 0;
48 | transition: top 200ms cubic-bezier(0, .8, .13, 1);
49 | background-color: rgba(79,192,141,0.5);
50 | }
51 | &:hover:after {
52 | top: 0%;
53 | }
54 | }
55 | }
--------------------------------------------------------------------------------
/react-blog/src/pages/web/archive/index.less:
--------------------------------------------------------------------------------
1 | .ant-card-body{
2 | padding: 24px;
3 | zoom: 1;
4 | }
--------------------------------------------------------------------------------
/react-blog/src/pages/web/header/index.js:
--------------------------------------------------------------------------------
1 | import React, { Component } from 'react'
2 | import { Layout, Row, Col, Menu } from 'antd'
3 | import { Link } from 'react-router-dom'
4 | import { SmileTwoTone,HomeOutlined } from '@ant-design/icons';
5 | import './index.less'
6 | import menus from '../../../Router/web'
7 |
8 | const { Header } = Layout
9 |
10 | class HeaderCustom extends Component {
11 | constructor(props) {
12 | super(props)
13 | this.state = {
14 | visible: false
15 | }
16 | }
17 |
18 | render () {
19 | const key = sessionStorage.getItem('webKey') || '0'
20 |
21 | //拿到menu为true字段的所有数据
22 | const list = menus.filter(v => v.menu)
23 | const menuList = list.map((item, i) => {
24 | return sessionStorage.setItem('webKey', String(i)) }>
25 |
26 |
27 | {item.title}
28 |
29 |
30 | })
31 | return (
32 |
33 |
34 |
35 |
36 |
37 | 旅梦博客开发
38 |
39 |
40 |
41 | {/* 对应webkey 使其在刷新后仍能停留在选中页面 */}
42 |
45 |
46 |
47 |
48 | )
49 | }
50 | }
51 |
52 | export default HeaderCustom
--------------------------------------------------------------------------------
/react-blog/src/pages/web/header/index.less:
--------------------------------------------------------------------------------
1 | .header-Container{
2 | background-color: #fff;
3 | padding: 0;
4 | .logo{
5 | width: 100%;
6 | height: 31px;
7 | line-height: 31px;
8 | margin: 16px 28px 16px 0;
9 | float: left;
10 | padding-left: 10px;
11 | }
12 | .ant-menu-horizontal{
13 | height: 64px;
14 | line-height: 64px;
15 | display: flex;
16 | justify-content: space-around;
17 | border-bottom: none;
18 | }
19 | }
--------------------------------------------------------------------------------
/react-blog/src/pages/web/layout/index.less:
--------------------------------------------------------------------------------
1 | .wrapper{
2 | height: 100%;
3 | .wrapper-container{
4 | height: 100%;
5 | .wrapper-content{
6 | height: 100%;
7 | &::-webkit-scrollbar{
8 | display: none;
9 | }
10 | }
11 | }
12 | .ant-layout-footer{
13 | text-align: center;
14 | }
15 | }
--------------------------------------------------------------------------------
/react-blog/src/pages/web/list/list.less:
--------------------------------------------------------------------------------
1 | .list-wrapper .ant-list-item {
2 | background: #fff;
3 | padding: 20px;
4 | margin-bottom: 10px;
5 | }
6 | .ant-list-item .ant-list-item-meta-title {
7 | font-size: 1.2rem;
8 | line-height: 1.2;
9 | /* color: #2e3135; */
10 | }
11 | .read-all {
12 | display: flex;
13 | flex-direction: row-reverse;
14 | }
15 | .list-item {
16 | cursor: pointer;
17 | }
18 | .list-wrapper .ant-list-vertical .ant-list-item-action>li {
19 | padding: 0 8px;
20 | }
21 | .ant-list-item{
22 | display: block;
23 | }
24 | .ant-list-item-action{
25 | margin-left: 0;
26 | margin-top: 24px;
27 | }
28 | .ant-list-item-meta-title{
29 | margin-bottom: 15px;
30 | }
--------------------------------------------------------------------------------
/react-blog/src/pages/web/sider/index.less:
--------------------------------------------------------------------------------
1 | .ant-card-body {
2 | padding: 0;
3 | }
4 | .sider-container
5 | .recent-list {
6 | width: 100%;
7 | }
8 | .sider-container
9 | .recent-list li {
10 | display: block;
11 | padding: 5px 24px;
12 | cursor: pointer;
13 | font-size: 14px;
14 | line-height: 32px;
15 | color: #8590a6;
16 | text-align: left;
17 | }
18 | .sider-container
19 | .recent-list {
20 | padding: 0;
21 | li:hover {
22 | color: rgb(0, 132, 255);
23 | background: rgb(246, 246, 246);
24 | }
25 | }
26 |
27 | .admin-info{
28 | background: #fff;
29 | margin-bottom: 20px;
30 | header{
31 | text-align: center;
32 | padding: 15px 0 0 0;
33 | img{
34 | width: 150px;
35 | height: 150px;
36 | max-width: 100%;
37 | border-radius: 50%;
38 | transition: transform 2s ease-out;
39 | &:hover{
40 | transform: rotateZ(360deg);
41 | }
42 | }
43 | }
44 | }
45 |
46 | .admin-name {
47 | text-align: center;
48 | font-weight: bold;
49 | padding: 8px 0 0;
50 | font-size: 1.5em;
51 | font-family: "Monospace Number", "Chinese Quote", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei", "Helvetica Neue", Helvetica, Arial, sans-serif;
52 | }
53 | .admin-desc {
54 | text-align: center;
55 | padding: 10px 15px 20px 15px;
56 | font-size: 14px;
57 | }
58 | .tags-wrapper {
59 | margin-top: 20px;
60 | .tags-content {
61 | padding: 0 20px 20px;
62 | }
63 | }
64 |
65 | .tags-content {
66 | padding: 20px;
67 | }
68 | .tags-content .ant-tag {
69 | margin: 6px;
70 | }
--------------------------------------------------------------------------------
/react-blog/src/pages/web/star/index.js:
--------------------------------------------------------------------------------
1 | import React, { Component } from 'react'
2 | import { List } from 'antd'
3 | import './star.less'
4 |
5 | class Collect extends Component {
6 | constructor(props) {
7 | super (props)
8 | this.state = {
9 | "data": [
10 | {
11 | "createdAt": "2019-04-10 10:19",
12 | "updatedAt": "2019-04-10 10:19",
13 | "id": 3,
14 | "title": "React 16 加载性能优化指南",
15 | "url": "https://juejin.im/post/5b506ae0e51d45191a0d4ec9"
16 | },
17 | {
18 | "createdAt": "2019-03-30 14:02",
19 | "updatedAt": "2019-03-30 14:02",
20 | "id": 2,
21 | "title": "CentOS7 系统目录详解和常用命令[文件和目录]",
22 | "url": "https://blog.csdn.net/qq_22860341/article/details/81363655"
23 | }
24 | ],
25 | "total": 2,
26 | "code": 1000,
27 | "desc": "success"
28 | }
29 | }
30 | render () {
31 | const pagination = {
32 | pageSize: 10,
33 | size: 'small',
34 | current: 1,
35 | total: 2,
36 |
37 | }
38 | return (
39 | 文章收藏}
43 | dataSource = {this.state.data}
44 | pagination={this.state.data.length ? pagination : null}
45 | renderItem = {item => (
46 |
47 | {item.title}]}>
48 |
49 | )}
50 | >
51 |
52 |
53 | )
54 | }
55 | }
56 |
57 | export default Collect
--------------------------------------------------------------------------------
/react-blog/src/pages/web/star/star.less:
--------------------------------------------------------------------------------
1 | .star-header {
2 | color: #000;
3 | font-size: 1.2em;
4 | }
5 | .star-list {
6 | background: #fff;
7 | padding: 0px 30px 20px 30px;
8 | }
9 |
10 | .star-list .ant-list-item-meta-description {
11 | color: black;
12 | }
13 |
14 | .star-list .ant-list-item {
15 | padding-bottom: 0;
16 | }
17 |
18 | .star-list .article-author {
19 | margin-left: 20px;
20 | }
--------------------------------------------------------------------------------
/react-blog/src/requireLogin.js:
--------------------------------------------------------------------------------
1 | import React from 'react'
2 |
3 | export default function requireLogin (Component) {
4 | // 组件有已经登录的模块, 直接返回(防止重新渲染)
5 | if (Component.requireLogin) {
6 | return Component.requireLogin
7 | }
8 |
9 | // 创建验证组件
10 | class requireLogin extends Component {
11 | constructor (props) {
12 | super(props)
13 | this.state = {
14 | login: true
15 | }
16 | }
17 |
18 | //组件挂载的时候判断
19 | componentWillMount() {
20 | this.checkAuth()
21 | }
22 |
23 | //退出登录
24 | componentWillReceiveProps () {
25 | this.checkAuth()
26 | }
27 |
28 |
29 | checkAuth () {
30 | // 判断登录
31 | const login = sessionStorage.getItem('blogUser')
32 | // 未登录, 重定向去到登录页面
33 | const pathname = this.props.location.pathname !== '/login'
34 | if( !login && pathname ){
35 | this.props.history.push('/login')
36 | return
37 | }
38 | }
39 | render() {
40 | if (this.state.login) {
41 | return
42 | }
43 | return ''
44 | }
45 | }
46 |
47 | Component.requireLogin = requireLogin
48 |
49 | return Component.requireLogin
50 | }
--------------------------------------------------------------------------------
/react-blog/src/setupTests.js:
--------------------------------------------------------------------------------
1 | // jest-dom adds custom jest matchers for asserting on DOM nodes.
2 | // allows you to do things like:
3 | // expect(element).toHaveTextContent(/react/i)
4 | // learn more: https://github.com/testing-library/jest-dom
5 | import '@testing-library/jest-dom/extend-expect';
6 |
--------------------------------------------------------------------------------
/react-blog/src/utils(公共方法)/index.js:
--------------------------------------------------------------------------------
1 | export const color = [
2 | 'magenta',
3 | 'red',
4 | 'volcano',
5 | 'orange',
6 | 'gold',
7 | 'lime',
8 | 'green',
9 | 'cyan',
10 | 'blue',
11 | 'geekblue',
12 | 'purple'
13 | ]
--------------------------------------------------------------------------------
/react-blog/src/utils(公共方法)/loadable.js:
--------------------------------------------------------------------------------
1 | import React, { Component } from 'react'
2 | import Loadable from 'react-loadable'
3 | import { Spin } from 'antd'
4 |
5 | const loadingComponet = ({ isLoading, error }) => {
6 | // Handle the loading state
7 | if (isLoading) {
8 | return
;
9 | }
10 | // Handle the error state
11 | else if (error) {
12 | return Sorry, there was a problem loading the page.
;
13 | }
14 | else {
15 | return null;
16 | }
17 | };
18 |
19 | export default (loader, loading = loadingComponet) => {
20 | return Loadable({
21 | loader,
22 | loading
23 | })
24 | }
25 |
--------------------------------------------------------------------------------
/react-comment/.gitignore:
--------------------------------------------------------------------------------
1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
2 |
3 | # dependencies
4 | /node_modules
5 | /.pnp
6 | .pnp.js
7 |
8 | # testing
9 | /coverage
10 |
11 | # production
12 | /build
13 |
14 | # misc
15 | .DS_Store
16 | .env.local
17 | .env.development.local
18 | .env.test.local
19 | .env.production.local
20 |
21 | npm-debug.log*
22 | yarn-debug.log*
23 | yarn-error.log*
24 |
--------------------------------------------------------------------------------
/react-comment/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "react-comment",
3 | "version": "0.1.0",
4 | "private": true,
5 | "dependencies": {
6 | "@testing-library/jest-dom": "^4.2.4",
7 | "@testing-library/react": "^9.3.2",
8 | "@testing-library/user-event": "^7.1.2",
9 | "react": "^16.12.0",
10 | "react-dom": "^16.12.0",
11 | "react-scripts": "3.3.0"
12 | },
13 | "scripts": {
14 | "start": "react-scripts start",
15 | "build": "react-scripts build",
16 | "test": "react-scripts test",
17 | "eject": "react-scripts eject"
18 | },
19 | "eslintConfig": {
20 | "extends": "react-app"
21 | },
22 | "browserslist": {
23 | "production": [
24 | ">0.2%",
25 | "not dead",
26 | "not op_mini all"
27 | ],
28 | "development": [
29 | "last 1 chrome version",
30 | "last 1 firefox version",
31 | "last 1 safari version"
32 | ]
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/react-comment/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dmCas/React-study/19cc2c81b77f0850c1e029050b260447c849624d/react-comment/public/favicon.ico
--------------------------------------------------------------------------------
/react-comment/public/logo192.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dmCas/React-study/19cc2c81b77f0850c1e029050b260447c849624d/react-comment/public/logo192.png
--------------------------------------------------------------------------------
/react-comment/public/logo512.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dmCas/React-study/19cc2c81b77f0850c1e029050b260447c849624d/react-comment/public/logo512.png
--------------------------------------------------------------------------------
/react-comment/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 | "src": "logo192.png",
12 | "type": "image/png",
13 | "sizes": "192x192"
14 | },
15 | {
16 | "src": "logo512.png",
17 | "type": "image/png",
18 | "sizes": "512x512"
19 | }
20 | ],
21 | "start_url": ".",
22 | "display": "standalone",
23 | "theme_color": "#000000",
24 | "background_color": "#ffffff"
25 | }
26 |
--------------------------------------------------------------------------------
/react-comment/public/robots.txt:
--------------------------------------------------------------------------------
1 | # https://www.robotstxt.org/robotstxt.html
2 | User-agent: *
3 |
--------------------------------------------------------------------------------
/react-comment/src/App.css:
--------------------------------------------------------------------------------
1 | .App {
2 | text-align: center;
3 | }
4 |
5 | .App-logo {
6 | height: 40vmin;
7 | pointer-events: none;
8 | }
9 |
10 | @media (prefers-reduced-motion: no-preference) {
11 | .App-logo {
12 | animation: App-logo-spin infinite 20s linear;
13 | }
14 | }
15 |
16 | .App-header {
17 | background-color: #282c34;
18 | min-height: 100vh;
19 | display: flex;
20 | flex-direction: column;
21 | align-items: center;
22 | justify-content: center;
23 | font-size: calc(10px + 2vmin);
24 | color: white;
25 | }
26 |
27 | .App-link {
28 | color: #61dafb;
29 | }
30 |
31 | @keyframes App-logo-spin {
32 | from {
33 | transform: rotate(0deg);
34 | }
35 | to {
36 | transform: rotate(360deg);
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/react-comment/src/App.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | // import logo from './logo.svg';
3 | import './App.css';
4 | import CommentInput from './CommentInput'
5 |
6 | class App extends React.Component {
7 | // 静态属性
8 | state = {
9 | commentList: [
10 |
11 | ]
12 | }
13 | onPublish = (userName, comment) => {
14 | // console.log(userName, comment);
15 | let c = {userName,comment}
16 | //不可变数据
17 | //指向同一个对象
18 | // let obj = {}; let obj1 = obj; obj1.name = 'li'
19 | // let obj1= Object.assign({}, obj)
20 | let list = this.state.commentList.slice(0);
21 | list.push(c)
22 | console.log(list)
23 | // this.state.commentList = list
24 | this.setState({
25 | commentList: list
26 | })
27 | }
28 | handleDel = (event) => {
29 | // del i ?
30 | // data-i
31 |
32 | const i = parseInt(event.target.dataset.i)
33 | const list = this.state.commentList.slice(0)
34 | list.splice(i,1);
35 | this.setState({
36 | commentList: list
37 | })
38 | }
39 | render() {
40 | return (
41 | <>
42 |
43 | { this.state.commentList.length }
44 | {/* */}
45 | {
46 | this.state.commentList && this.state.commentList.map(
47 | (c, i) => {
48 | return (
49 |
50 | {c.userName}: {c.comment}
51 |
52 |
53 | )
54 | }
55 | )
56 | }
57 | >
58 | )
59 | }
60 | }
61 |
62 | export default App;
63 |
--------------------------------------------------------------------------------
/react-comment/src/App.test.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { render } from '@testing-library/react';
3 | import App from './App';
4 |
5 | test('renders learn react link', () => {
6 | const { getByText } = render();
7 | const linkElement = getByText(/learn react/i);
8 | expect(linkElement).toBeInTheDocument();
9 | });
10 |
--------------------------------------------------------------------------------
/react-comment/src/CommentInput.jsx:
--------------------------------------------------------------------------------
1 | import React from 'react'
2 |
3 | class CommentInput extends React.Component{
4 |
5 | handlePublish = () => {
6 | const userName = this.refs.userName.value;
7 | const comment = this.refs.comment.value;
8 | // 通知父组件 存在数组里面
9 | const { onPublish } = this.props;
10 | onPublish(userName, comment)
11 | }
12 | render() {
13 | return (
14 | <>
15 | 用户名:
16 | 评论内容:
17 |
18 | >
19 | )
20 | }
21 | }
22 | export default CommentInput;
--------------------------------------------------------------------------------
/react-comment/src/index.css:
--------------------------------------------------------------------------------
1 | body {
2 | margin: 0;
3 | font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen',
4 | 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue',
5 | sans-serif;
6 | -webkit-font-smoothing: antialiased;
7 | -moz-osx-font-smoothing: grayscale;
8 | }
9 |
10 | code {
11 | font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New',
12 | monospace;
13 | }
14 |
--------------------------------------------------------------------------------
/react-comment/src/index.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import ReactDOM from 'react-dom';
3 | import './index.css';
4 | import App from './App';
5 | import * as serviceWorker from './serviceWorker';
6 |
7 | ReactDOM.render(, document.getElementById('root'));
8 |
9 | // If you want your app to work offline and load faster, you can change
10 | // unregister() to register() below. Note this comes with some pitfalls.
11 | // Learn more about service workers: https://bit.ly/CRA-PWA
12 | serviceWorker.unregister();
13 |
--------------------------------------------------------------------------------
/react-comment/src/setupTests.js:
--------------------------------------------------------------------------------
1 | // jest-dom adds custom jest matchers for asserting on DOM nodes.
2 | // allows you to do things like:
3 | // expect(element).toHaveTextContent(/react/i)
4 | // learn more: https://github.com/testing-library/jest-dom
5 | import '@testing-library/jest-dom/extend-expect';
6 |
--------------------------------------------------------------------------------
/react-demo/LifeCycle.js:
--------------------------------------------------------------------------------
1 | import React, { Component } from 'react'
2 |
3 | class LifeCycle extends Component {
4 | constructor (props) {
5 | super(props)
6 | console.log('1. 构造函数')
7 | this.state = {
8 | msg: '来自属性传递' + props.prop
9 | }
10 | }
11 | componentWillMount () {
12 | // 此时可以访问属性和状态,可以进行api调用 但是没有办法做dom相关操作
13 | // console.log(this.state.msg)
14 | console.log('2. 组件将要挂载')
15 | }
16 | componentDidMount () {
17 | // 组件已经渲染完成, 可以进行状态更新操作
18 | console.log('3. 组件已挂载')
19 | }
20 | componentWillReceiveProps () {
21 | // 父组件传递的属性有变化, 做相应的操作
22 | console.log('4. 组件属性更新了')
23 | }
24 | shouldComponentUpdate () {
25 | // 组件是否需要更新, 返回boolean
26 | console.log('5. 组件是否需要更新?')
27 | return true
28 | }
29 | componentWillUpdate () {
30 | console.log('6. 组件将要更新')
31 | }
32 | componentDidUpdate () {
33 | console.log('7. 组件已经更新')
34 | }
35 | render () {
36 | console.log('组件渲染')
37 | return (
38 | 组件生命周期探究
39 | )
40 | }
41 | }
42 |
43 | export default class extends Component {
44 | constructor(props){
45 | super(props)
46 | this.state = {
47 | someProp: '北辰'
48 | }
49 |
50 | setTimeout (() => {
51 | this.setState({
52 | someProp: 'beichen'
53 | })
54 | }, 2000)
55 | }
56 | render () {
57 | return
58 | }
59 | }
60 |
61 |
--------------------------------------------------------------------------------
/react-demo/demo1/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 | Document
11 |
12 |
13 |
14 |
15 |
21 |
22 |
--------------------------------------------------------------------------------
/react-demo/demo10/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 | Document
11 |
12 |
13 |
14 |
15 |
53 |
54 |
--------------------------------------------------------------------------------
/react-demo/demo11/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 | Document
12 |
13 |
14 |
15 |
16 |
51 |
52 |
--------------------------------------------------------------------------------
/react-demo/demo2/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 | Document
11 |
12 |
13 |
14 |
15 |
28 |
29 |
--------------------------------------------------------------------------------
/react-demo/demo3/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 | Document
11 |
12 |
13 |
14 |
15 |
29 |
30 |
--------------------------------------------------------------------------------
/react-demo/demo4/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 | Document
11 |
12 |
13 |
14 |
15 |
29 |
30 |
--------------------------------------------------------------------------------
/react-demo/demo5/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 | Document
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
50 |
51 |
--------------------------------------------------------------------------------
/react-demo/demo6/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 | Document
12 |
13 |
14 |
15 |
16 |
17 |
40 |
41 |
--------------------------------------------------------------------------------
/react-demo/demo7/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 | Document
11 |
12 |
13 |
14 |
15 |
43 |
44 |
--------------------------------------------------------------------------------
/react-demo/demo8/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 | Document
11 |
12 |
13 |
14 |
15 |
16 |
17 |
50 |
51 |
--------------------------------------------------------------------------------
/react-demo/demo9(实现节流)/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 | Document
11 |
12 |
13 |
14 |
15 |
16 |
52 |
53 |
--------------------------------------------------------------------------------
/react-hoc/.gitignore:
--------------------------------------------------------------------------------
1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
2 |
3 | # dependencies
4 | /node_modules
5 | /.pnp
6 | .pnp.js
7 |
8 | # testing
9 | /coverage
10 |
11 | # production
12 | /build
13 |
14 | # misc
15 | .DS_Store
16 | .env.local
17 | .env.development.local
18 | .env.test.local
19 | .env.production.local
20 |
21 | npm-debug.log*
22 | yarn-debug.log*
23 | yarn-error.log*
24 |
--------------------------------------------------------------------------------
/react-hoc/README.md:
--------------------------------------------------------------------------------
1 | # HOC
2 | higher order Component
3 |
4 | # 组件
5 | 是对 公共 html css state 的一个抽象
6 |
7 | # 高阶组件
8 | 是对 各个组件中 公共逻辑的一个抽象
9 | 1. 防止重复的代码 (页面复用) 降低代码的耦合度
10 | 2. 条件渲染 控制组件的渲染逻辑 (渲染劫持)
11 | 3. 捕获|劫持被处理的生命周期
12 |
13 |
--------------------------------------------------------------------------------
/react-hoc/config/jest/cssTransform.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | // This is a custom Jest transformer turning style imports into empty objects.
4 | // http://facebook.github.io/jest/docs/en/webpack.html
5 |
6 | module.exports = {
7 | process() {
8 | return 'module.exports = {};';
9 | },
10 | getCacheKey() {
11 | // The output is always the same.
12 | return 'cssTransform';
13 | },
14 | };
15 |
--------------------------------------------------------------------------------
/react-hoc/config/jest/fileTransform.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | const path = require('path');
4 | const camelcase = require('camelcase');
5 |
6 | // This is a custom Jest transformer turning file imports into filenames.
7 | // http://facebook.github.io/jest/docs/en/webpack.html
8 |
9 | module.exports = {
10 | process(src, filename) {
11 | const assetFilename = JSON.stringify(path.basename(filename));
12 |
13 | if (filename.match(/\.svg$/)) {
14 | // Based on how SVGR generates a component name:
15 | // https://github.com/smooth-code/svgr/blob/01b194cf967347d43d4cbe6b434404731b87cf27/packages/core/src/state.js#L6
16 | const pascalCaseFilename = camelcase(path.parse(filename).name, {
17 | pascalCase: true,
18 | });
19 | const componentName = `Svg${pascalCaseFilename}`;
20 | return `const React = require('react');
21 | module.exports = {
22 | __esModule: true,
23 | default: ${assetFilename},
24 | ReactComponent: React.forwardRef(function ${componentName}(props, ref) {
25 | return {
26 | $$typeof: Symbol.for('react.element'),
27 | type: 'svg',
28 | ref: ref,
29 | key: null,
30 | props: Object.assign({}, props, {
31 | children: ${assetFilename}
32 | })
33 | };
34 | }),
35 | };`;
36 | }
37 |
38 | return `module.exports = ${assetFilename};`;
39 | },
40 | };
41 |
--------------------------------------------------------------------------------
/react-hoc/config/pnpTs.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | const { resolveModuleName } = require('ts-pnp');
4 |
5 | exports.resolveModuleName = (
6 | typescript,
7 | moduleName,
8 | containingFile,
9 | compilerOptions,
10 | resolutionHost
11 | ) => {
12 | return resolveModuleName(
13 | moduleName,
14 | containingFile,
15 | compilerOptions,
16 | resolutionHost,
17 | typescript.resolveModuleName
18 | );
19 | };
20 |
21 | exports.resolveTypeReferenceDirective = (
22 | typescript,
23 | moduleName,
24 | containingFile,
25 | compilerOptions,
26 | resolutionHost
27 | ) => {
28 | return resolveModuleName(
29 | moduleName,
30 | containingFile,
31 | compilerOptions,
32 | resolutionHost,
33 | typescript.resolveTypeReferenceDirective
34 | );
35 | };
36 |
--------------------------------------------------------------------------------
/react-hoc/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dmCas/React-study/19cc2c81b77f0850c1e029050b260447c849624d/react-hoc/public/favicon.ico
--------------------------------------------------------------------------------
/react-hoc/public/logo192.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dmCas/React-study/19cc2c81b77f0850c1e029050b260447c849624d/react-hoc/public/logo192.png
--------------------------------------------------------------------------------
/react-hoc/public/logo512.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dmCas/React-study/19cc2c81b77f0850c1e029050b260447c849624d/react-hoc/public/logo512.png
--------------------------------------------------------------------------------
/react-hoc/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 | "src": "logo192.png",
12 | "type": "image/png",
13 | "sizes": "192x192"
14 | },
15 | {
16 | "src": "logo512.png",
17 | "type": "image/png",
18 | "sizes": "512x512"
19 | }
20 | ],
21 | "start_url": ".",
22 | "display": "standalone",
23 | "theme_color": "#000000",
24 | "background_color": "#ffffff"
25 | }
26 |
--------------------------------------------------------------------------------
/react-hoc/public/robots.txt:
--------------------------------------------------------------------------------
1 | # https://www.robotstxt.org/robotstxt.html
2 | User-agent: *
3 | Disallow:
4 |
--------------------------------------------------------------------------------
/react-hoc/scripts/test.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | // Do this as the first thing so that any code reading it knows the right env.
4 | process.env.BABEL_ENV = 'test';
5 | process.env.NODE_ENV = 'test';
6 | process.env.PUBLIC_URL = '';
7 |
8 | // Makes the script crash on unhandled rejections instead of silently
9 | // ignoring them. In the future, promise rejections that are not handled will
10 | // terminate the Node.js process with a non-zero exit code.
11 | process.on('unhandledRejection', err => {
12 | throw err;
13 | });
14 |
15 | // Ensure environment variables are read.
16 | require('../config/env');
17 |
18 |
19 | const jest = require('jest');
20 | const execSync = require('child_process').execSync;
21 | let argv = process.argv.slice(2);
22 |
23 | function isInGitRepository() {
24 | try {
25 | execSync('git rev-parse --is-inside-work-tree', { stdio: 'ignore' });
26 | return true;
27 | } catch (e) {
28 | return false;
29 | }
30 | }
31 |
32 | function isInMercurialRepository() {
33 | try {
34 | execSync('hg --cwd . root', { stdio: 'ignore' });
35 | return true;
36 | } catch (e) {
37 | return false;
38 | }
39 | }
40 |
41 | // Watch unless on CI or explicitly running all tests
42 | if (
43 | !process.env.CI &&
44 | argv.indexOf('--watchAll') === -1 &&
45 | argv.indexOf('--watchAll=false') === -1
46 | ) {
47 | // https://github.com/facebook/create-react-app/issues/5210
48 | const hasSourceControl = isInGitRepository() || isInMercurialRepository();
49 | argv.push(hasSourceControl ? '--watch' : '--watchAll');
50 | }
51 |
52 |
53 | jest.run(argv);
54 |
--------------------------------------------------------------------------------
/react-hoc/src/App.css:
--------------------------------------------------------------------------------
1 | .App {
2 | text-align: center;
3 | }
4 |
5 | .App-logo {
6 | height: 40vmin;
7 | pointer-events: none;
8 | }
9 |
10 | @media (prefers-reduced-motion: no-preference) {
11 | .App-logo {
12 | animation: App-logo-spin infinite 20s linear;
13 | }
14 | }
15 |
16 | .App-header {
17 | background-color: #282c34;
18 | min-height: 100vh;
19 | display: flex;
20 | flex-direction: column;
21 | align-items: center;
22 | justify-content: center;
23 | font-size: calc(10px + 2vmin);
24 | color: white;
25 | }
26 |
27 | .App-link {
28 | color: #61dafb;
29 | }
30 |
31 | @keyframes App-logo-spin {
32 | from {
33 | transform: rotate(0deg);
34 | }
35 | to {
36 | transform: rotate(360deg);
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/react-hoc/src/App.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import logo from './logo.svg';
3 | import './App.css';
4 |
5 | function App() {
6 | return (
7 |
23 | );
24 | }
25 |
26 | export default App;
27 |
--------------------------------------------------------------------------------
/react-hoc/src/App.test.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { render } from '@testing-library/react';
3 | import App from './App';
4 |
5 | test('renders learn react link', () => {
6 | const { getByText } = render();
7 | const linkElement = getByText(/learn react/i);
8 | expect(linkElement).toBeInTheDocument();
9 | });
10 |
--------------------------------------------------------------------------------
/react-hoc/src/component/example1/index.js:
--------------------------------------------------------------------------------
1 | import React from 'react'
2 |
3 | const withMosu = (Component) => {
4 | return class extends React.Component {
5 | state = { x: 0, y: 0}
6 | handleMouseMove = (event) => {
7 | this.setState({
8 | x: event.clientX,
9 | y: event.clientY
10 | })
11 | console.log(event)
12 | }
13 | render () {
14 | return (
15 |
16 |
17 |
18 | )
19 | }
20 | }
21 | }
22 |
23 | // 定义一个纯函数无状态的组件
24 | const App = (props) => {
25 | const { x, y } = props.mouse
26 | return (
27 |
28 |
The mouse position is ({x}, {y})
29 |
30 | )
31 | }
32 |
33 | // const test = () => {
34 | // return (
35 | // {x}, {y}
36 | // )
37 | // }
38 |
39 | const AppWithMouse = withMosu(App) // 高阶组件替组件干活
40 |
41 | export default AppWithMouse
--------------------------------------------------------------------------------
/react-hoc/src/component/example2/index.js:
--------------------------------------------------------------------------------
1 | import React, { Component } from 'react'
2 |
3 | // HOC 高阶组件
4 |
5 | function HOC( WrappedComponent ) {
6 | return class extends Component {
7 | constructor (props) {
8 | super(props)
9 | this.state = {
10 | name: ''
11 | }
12 | }
13 | onChange = ( event ) => {
14 | // this.setState 在这里!!!是异步的
15 | this.setState({
16 | name: event.target.value
17 | })
18 | console.log(this.state.name)
19 | }
20 |
21 | render () {
22 | const newProps = {
23 | name: {
24 | value: this.state.name,
25 | onChange: this.onChange
26 | }
27 | }
28 | return
29 | }
30 | }
31 | }
32 |
33 | // 使用
34 | @HOC
35 | class Example extends Component {
36 | render () {
37 | return (
38 |
39 | )
40 | }
41 | }
42 |
43 | // const Example = HOC(Example)
44 | export default Example
--------------------------------------------------------------------------------
/react-hoc/src/component/example3/OperateRefsHOC.js:
--------------------------------------------------------------------------------
1 | import React from 'react'
2 |
3 | function HOC (WrappedComponent) {
4 | let inputElement = null
5 |
6 | function handleClick() {
7 | inputElement.focus()
8 | }
9 |
10 | return ( props ) => (
11 |
12 | {inputElement = el}}/>
13 |
14 |
15 | )
16 | }
17 |
18 | export default HOC
--------------------------------------------------------------------------------
/react-hoc/src/component/example3/index.js:
--------------------------------------------------------------------------------
1 | import React from 'react'
2 | import User from './user'
3 | import HOC from './OperateRefsHOC'
4 |
5 | const EnhanceUser = HOC(User)
6 |
7 | class OperateRefs extends React.Component {
8 | render () {
9 | return
10 | }
11 | }
12 |
13 | export default OperateRefs
--------------------------------------------------------------------------------
/react-hoc/src/component/example3/user.js:
--------------------------------------------------------------------------------
1 | import React from 'react'
2 |
3 |
4 | class User extends React.Component {
5 | inputElement = null
6 |
7 | sayHello () {
8 | console.log('hello world')
9 | }
10 |
11 | constructor(props) {
12 | super(props)
13 | this.focus = this.focus.bind(this)
14 | this.onChaneg = this.focus.bind(this)
15 | }
16 |
17 | state = {
18 | name: '',
19 | age: 0
20 | }
21 |
22 | focus () {
23 | this.inputElement.focus()
24 | }
25 |
26 | onChange = (e) => {
27 | this.setState({
28 | age: e.target.value
29 | })
30 | }
31 |
32 | componentDidMount() {
33 | this.setState({
34 | name: this.props.name,
35 | age: this.props.age
36 | })
37 | }
38 |
39 | render () {
40 | return (
41 |
42 |
姓名: {this.state.name}
43 |
44 | 年龄:
45 | {
48 | if (this.props.inputRef) {
49 | this.props.inputRef(input) // 父组件传入的ref回调函数
50 | }
51 | this.inputElement = input
52 | }}>
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 | )
62 | }
63 | }
64 |
65 | export default User
--------------------------------------------------------------------------------
/react-hoc/src/component/useRef/Use.js:
--------------------------------------------------------------------------------
1 | import React, { useState, useEffect, useRef } from 'react'
2 |
3 | function Example () {
4 | const inputEl = useRef(null)
5 |
6 | const onButtonClick = () => {
7 | inputEl.current.value = '猛哥aaaa'
8 | console.log(inputEl)
9 | }
10 |
11 | const [text, setText] = useState('猛哥')
12 | const textRef = useRef()
13 |
14 | // 初次渲染执行
15 | useEffect(() => {
16 | textRef.current = text
17 | console.log(textRef.current)
18 | })
19 |
20 | return (
21 |
22 |
23 |
24 |
25 | {setText(e.target.value)}}>
26 |
27 | )
28 | }
29 |
30 | export default Example
--------------------------------------------------------------------------------
/react-hoc/src/component/useRef/index.js:
--------------------------------------------------------------------------------
1 | // useRef 获取DOM元素
2 | // useRef 保存普通变量
3 | import React, { useRef } from 'react'
4 |
5 | function Example () {
6 | // inputEl这个变量是useRef函数的返回值,那么这个变量给谁当ref属性,就能表示该元素的DOM
7 | const inputEl = useRef(null)
8 |
9 | const onButtonClick = () =>{
10 | inputEl.current.value = '猛哥贼帅'
11 | console.log(inputEl)
12 | }
13 |
14 | return (
15 |
16 |
17 |
18 |
19 | )
20 | }
21 |
22 | export default Example
23 |
--------------------------------------------------------------------------------
/react-hoc/src/index.css:
--------------------------------------------------------------------------------
1 | body {
2 | margin: 0;
3 | font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen',
4 | 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue',
5 | sans-serif;
6 | -webkit-font-smoothing: antialiased;
7 | -moz-osx-font-smoothing: grayscale;
8 | }
9 |
10 | code {
11 | font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New',
12 | monospace;
13 | }
14 |
--------------------------------------------------------------------------------
/react-hoc/src/index.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import ReactDOM from 'react-dom';
3 | import './index.css';
4 | import App from './component/example2';
5 | import Example3 from './component/example3';
6 | import * as serviceWorker from './serviceWorker';
7 | import Demo6 from './component/useRef'
8 | import AnotherDemo6 from './component/useRef/Use'
9 | // ReactDOM.render(, document.getElementById('root'));
10 | // ReactDOM.render(, document.getElementById('root'));
11 | ReactDOM.render(, document.getElementById('root'));
12 | // If you want your app to work offline and load faster, you can change
13 | // unregister() to register() below. Note this comes with some pitfalls.
14 | // Learn more about service workers: https://bit.ly/CRA-PWA
15 | serviceWorker.unregister();
16 |
--------------------------------------------------------------------------------
/react-hoc/src/setupTests.js:
--------------------------------------------------------------------------------
1 | // jest-dom adds custom jest matchers for asserting on DOM nodes.
2 | // allows you to do things like:
3 | // expect(element).toHaveTextContent(/react/i)
4 | // learn more: https://github.com/testing-library/jest-dom
5 | import '@testing-library/jest-dom/extend-expect';
6 |
--------------------------------------------------------------------------------
/react-hook/.gitignore:
--------------------------------------------------------------------------------
1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
2 |
3 | # dependencies
4 | /node_modules
5 | /.pnp
6 | .pnp.js
7 |
8 | # testing
9 | /coverage
10 |
11 | # production
12 | /build
13 |
14 | # misc
15 | .DS_Store
16 | .env.local
17 | .env.development.local
18 | .env.test.local
19 | .env.production.local
20 |
21 | npm-debug.log*
22 | yarn-debug.log*
23 | yarn-error.log*
24 |
--------------------------------------------------------------------------------
/react-hook/README.md:
--------------------------------------------------------------------------------
1 | - hooks 本质上就是一类特殊的函数 目的就是让你不再写 class, 让function一统江湖
2 | # useState 就是一个hook
3 | import React, { useState } from 'react';
4 |
5 | function Example() {
6 | // 声明一个新的叫做 “count” 的 state 变量
7 | const [count, setCount] = useState(0);
8 |
9 | return (
10 |
11 |
You clicked {count} times
12 |
15 |
16 | );
17 |
18 | # react 是如何保证useState找到自己对应的state
19 | 1. 是根据useState出现的顺序来确定的
20 | 2. React hooks 不能出现再条件判断语句中, 因为他必须有完全一样的渲染顺序
21 |
22 | # componentWillUpdate
23 | 数据源更改时执行该生命周期
24 | 是再setState执行时,数据源更改之前执行
25 |
26 | ## useEffect
27 | 1. React 首次渲染和之后的每一次渲染都会调用useEffect
28 | 2. useEffect里面定义的函数是异步执行的,他不会阻碍浏览器更新视图
29 |
30 | ## useContext
31 | **使父子组件的传值变得更加简单**
32 |
33 | ## useMemo
34 | 优化Hooks一些缺陷
35 |
--------------------------------------------------------------------------------
/react-hook/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "react-hook",
3 | "version": "0.1.0",
4 | "private": true,
5 | "dependencies": {
6 | "@testing-library/jest-dom": "^4.2.4",
7 | "@testing-library/react": "^9.3.2",
8 | "@testing-library/user-event": "^7.1.2",
9 | "antd": "^4.2.0",
10 | "core-js": "^2.6.11",
11 | "react": "^16.13.0",
12 | "react-dom": "^16.13.0",
13 | "react-router-dom": "^5.1.2",
14 | "react-scripts": "3.4.0",
15 | "recharts": "^1.8.5"
16 | },
17 | "scripts": {
18 | "start": "react-scripts start",
19 | "build": "react-scripts build",
20 | "test": "react-scripts test",
21 | "eject": "react-scripts eject"
22 | },
23 | "eslintConfig": {
24 | "extends": "react-app"
25 | },
26 | "browserslist": {
27 | "production": [
28 | ">0.2%",
29 | "not dead",
30 | "not op_mini all"
31 | ],
32 | "development": [
33 | "last 1 chrome version",
34 | "last 1 firefox version",
35 | "last 1 safari version"
36 | ]
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/react-hook/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dmCas/React-study/19cc2c81b77f0850c1e029050b260447c849624d/react-hook/public/favicon.ico
--------------------------------------------------------------------------------
/react-hook/public/logo192.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dmCas/React-study/19cc2c81b77f0850c1e029050b260447c849624d/react-hook/public/logo192.png
--------------------------------------------------------------------------------
/react-hook/public/logo512.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dmCas/React-study/19cc2c81b77f0850c1e029050b260447c849624d/react-hook/public/logo512.png
--------------------------------------------------------------------------------
/react-hook/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 | "src": "logo192.png",
12 | "type": "image/png",
13 | "sizes": "192x192"
14 | },
15 | {
16 | "src": "logo512.png",
17 | "type": "image/png",
18 | "sizes": "512x512"
19 | }
20 | ],
21 | "start_url": ".",
22 | "display": "standalone",
23 | "theme_color": "#000000",
24 | "background_color": "#ffffff"
25 | }
26 |
--------------------------------------------------------------------------------
/react-hook/public/robots.txt:
--------------------------------------------------------------------------------
1 | # https://www.robotstxt.org/robotstxt.html
2 | User-agent: *
3 | Disallow:
4 |
--------------------------------------------------------------------------------
/react-hook/src/App.css:
--------------------------------------------------------------------------------
1 | .App {
2 | width: 1200px;
3 | margin: auto;
4 | text-align: center;
5 | }
6 | body{
7 | text-align: center;
8 | }
9 |
10 | .history-group {
11 | display: flex;
12 | justify-content: center;
13 | width: 1200px;
14 | margin: auto;
15 | }
16 |
17 | table,
18 | th,
19 | td {
20 | border: 1px solid #ccc;
21 | border-collapse: collapse;
22 | }
23 |
24 | th,
25 | td {
26 | padding: 5px;
27 | text-align: left;
28 | }
29 |
30 | .global-stats > table {
31 | margin: auto;
32 | margin-top: 0.5rem;
33 | margin-bottom: 1rem;
34 | }
--------------------------------------------------------------------------------
/react-hook/src/App.js:
--------------------------------------------------------------------------------
1 | import React, { useEffect, useState } from 'react';
2 | import logo from './logo.svg';
3 | import './App.css';
4 | // import axios from 'axios'
5 | import GlobalStats from './component/useEffect/demo'
6 | import CountriesChart from './component/useEffect/CountriesChart'
7 | import SelectDataKey from './component/useEffect/SelectDataKey'
8 | const BASE_URL = "https://corona.lmao.ninja";
9 | function App() {
10 | const [globalStats, setGlobalStats] = useState({});
11 | const [countries, setCountries] = useState([])
12 | const [key, setKey] = useState('cases')
13 | // useEffect(() => {
14 | // axios.get(`${BASE_URL}/v2/all`).then((res) => {
15 | // console.log(res)
16 | // setGlobalStats(res.data)
17 | // })
18 | // }, [])
19 | useEffect(() => {
20 | const fetchGlobalStats = async () => {
21 | const response = await fetch(`${BASE_URL}/v2/all`);
22 | const data = await response.json();
23 | console.log(data)
24 | setGlobalStats(data);
25 | };
26 |
27 | fetchGlobalStats();
28 | const intervalId = setInterval(fetchGlobalStats, 10000);
29 |
30 | return () => clearInterval(intervalId);
31 | }, [])
32 |
33 | useEffect(() => {
34 | const fetchCountries = async () => {
35 | const response = await fetch(`${BASE_URL}/v2/countries?sort=${key}`);
36 | const data = await response.json();
37 | console.log(data)
38 | setCountries(data.slice(0, 10));
39 | };
40 | fetchCountries()
41 | }, [key])
42 |
43 | return (
44 |
45 |
新型冠状病毒
46 |
47 | setKey(e.target.value)} />
48 |
49 |
50 | )
51 | }
52 |
53 | export default App;
54 |
--------------------------------------------------------------------------------
/react-hook/src/App.test.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { render } from '@testing-library/react';
3 | import App from './App';
4 |
5 | test('renders learn react link', () => {
6 | const { getByText } = render();
7 | const linkElement = getByText(/learn react/i);
8 | expect(linkElement).toBeInTheDocument();
9 | });
10 |
--------------------------------------------------------------------------------
/react-hook/src/component/useEffect/index.js:
--------------------------------------------------------------------------------
1 | import React, { Component } from 'react'
2 |
3 | class Example extends Component {
4 | constructor(props) {
5 | super(props)
6 | this.state = {
7 | count: [0]
8 | }
9 | }
10 |
11 | // 组件初次渲染执行
12 | componentDidMount() {
13 | console.log(`你点击了 ${this.state.count}次`)
14 | this.setState({
15 | count:[0,1]
16 | },() => {
17 | console.log(this.state.count)
18 | setTimeout(() => {
19 | var a = this.state.count
20 | a.push(2)
21 | this.setState({
22 | count:a
23 | },() => {
24 | console.log(this.state.count)
25 | })
26 | }, 30000);
27 | })
28 | }
29 |
30 | componentDidUpdate () {
31 | console.log(`你点击了 ${this.state.count}次`)
32 | }
33 |
34 | shouldComponentUpdate(){
35 | return true
36 | }
37 |
38 | addCount () {
39 | this.setState({
40 | count: this.state.count + 1
41 | })
42 | }
43 |
44 | render () {
45 | return (
46 |
47 |
你点了{this.state.count}次
48 |
49 |
50 | )
51 | }
52 | }
53 |
54 | export default Example
--------------------------------------------------------------------------------
/react-hook/src/component/useEffect/indexHook.js:
--------------------------------------------------------------------------------
1 | // 副作用 -- hooks模式下状态 {state} 发生变更的时候提供给我们做额外操作的地方
2 | import React, { useState, useEffect } from 'react'
3 | function Example () {
4 | const [ count, setCount ] = useState(0)
5 |
6 | // 不需要考虑时间刻度
7 | // 首次渲染和每一次渲染都会执行
8 | useEffect(() => {
9 | console.log(`你点击了 ${count}次`)
10 | // axios.get('http://musicapi.leanapp.cn/comment/music?id=186016&limit=1').then(
11 | // (res) => {
12 | // const data = res.data
13 | // console.log(data)
14 | // }
15 | // )
16 | })
17 |
18 | return (
19 |
20 |
你点了{count}次
21 |
22 |
23 | )
24 | }
25 |
26 | export default Example
27 |
28 |
--------------------------------------------------------------------------------
/react-hook/src/component/useEffect/makeUnmount.js:
--------------------------------------------------------------------------------
1 | // componentWillUnmount 组件卸载之前
2 | // useEffect 实现组件componentWillUnmount (解绑副作用)
3 |
4 | import { BrowserRouter as Router, Route, Link } from 'react-router-dom'
5 | // 副作用 -- hooks模式下状态 {state} 发生变更的时候提供给我们做额外操作的地方
6 | import React, { useState, useEffect } from 'react'
7 | function Example () {
8 | const [ count, setCount ] = useState(0)
9 |
10 | // 不需要考虑时间刻度
11 | // 首次渲染和每一次渲染都会执行
12 | useEffect(() => {
13 | console.log(`你点击了 ${count}次`)
14 |
15 | return () => {
16 | console.log('-----------------你离开了页面,组件卸载')
17 | }
18 | },[])
19 |
20 | return (
21 |
22 |
你点了{count}次
23 |
24 |
25 |
26 |
27 | - 首页
28 | -
29 | 列表
30 |
31 |
32 |
33 |
34 |
35 |
36 | )
37 | }
38 |
39 | function Index () {
40 | useEffect(() => {
41 | console.log('useEffect => 这里是Index页面')
42 | return () => {
43 | console.log('你离开了Index页面')
44 | }
45 | }, [])
46 | return React Hooks
47 | }
48 |
49 | function List () {
50 | useEffect(() => {
51 | console.log('useEffect => 这里是List页面')
52 | }, [])//[] 组件被销毁的时候进行解绑
53 | return List-Page
54 | }
55 |
56 | export default Example
57 |
58 |
--------------------------------------------------------------------------------
/react-hook/src/component/useState/index.js:
--------------------------------------------------------------------------------
1 | import React, { Component } from 'react'
2 |
3 | class Example extends Component {
4 | constructor(props) {
5 | super(props)
6 | this.state = {
7 | count: 0
8 | }
9 | }
10 |
11 | addCount () {
12 | this.setState({
13 | count: this.state.count + 1
14 | })
15 | }
16 |
17 | render () {
18 | return (
19 |
20 |
你点了{this.state.count}次
21 |
22 |
23 | )
24 | }
25 | }
26 |
27 | export default Example
--------------------------------------------------------------------------------
/react-hook/src/component/useState/indexHook.js:
--------------------------------------------------------------------------------
1 | import React, { useState } from 'react'
2 | // useState 就是一个hook
3 |
4 | function Example () {
5 | const [ count, setCount ] = useState(0)
6 |
7 | // let _useState = useState(0)
8 | // let count = _useState[0]
9 | // let setCount = _useState[1]
10 |
11 | // setCount == this.setState({ count : 'number'})
12 | return (
13 |
14 |
你点了{count}次
15 |
16 |
17 | )
18 | }
19 |
20 | // let showSex = true
21 | // function Example2 () {
22 | // // const [ count, name, age, setCount, setName, setAge ] = useState(0, "蜗牛", 18)
23 | // const [ age, setAge ] = useState(18)
24 | // if(showSex){
25 | // const [ sex, setSex ] = useState('男')
26 | // showSex = false
27 | // }
28 |
29 | // const [ work, setWork ] = useState('前端程序员')
30 |
31 | // // react 是如何保证useState找到自己对应的state
32 | // // react 是根据useState出现的顺序来确定的
33 |
34 | // return (
35 | //
36 | //
setAge( age+ 1)}>江军 今年: {age}岁
37 | //
性别: {sex}
38 | //
工作是: {work}
39 | //
40 | // )
41 | // }
42 |
43 | export default Example
44 |
45 | // hooks 本质上就是一类特殊的函数 目的就是让你不再写 class, 让function一统江湖
--------------------------------------------------------------------------------
/react-hook/src/index.css:
--------------------------------------------------------------------------------
1 | body {
2 | padding: 0;
3 | margin: 0;
4 | font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen',
5 | 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue',
6 | sans-serif;
7 | -webkit-font-smoothing: antialiased;
8 | -moz-osx-font-smoothing: grayscale;
9 | }
10 |
11 | code {
12 | font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New',
13 | monospace;
14 | }
15 |
--------------------------------------------------------------------------------
/react-hook/src/setupTests.js:
--------------------------------------------------------------------------------
1 | // jest-dom adds custom jest matchers for asserting on DOM nodes.
2 | // allows you to do things like:
3 | // expect(element).toHaveTextContent(/react/i)
4 | // learn more: https://github.com/testing-library/jest-dom
5 | import '@testing-library/jest-dom/extend-expect';
6 |
--------------------------------------------------------------------------------
/react-jianshu/.gitignore:
--------------------------------------------------------------------------------
1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
2 |
3 | # dependencies
4 | /node_modules
5 | /.pnp
6 | .pnp.js
7 |
8 | # testing
9 | /coverage
10 |
11 | # production
12 | /build
13 |
14 | # misc
15 | .DS_Store
16 | .env.local
17 | .env.development.local
18 | .env.test.local
19 | .env.production.local
20 |
21 | npm-debug.log*
22 | yarn-debug.log*
23 | yarn-error.log*
24 |
--------------------------------------------------------------------------------
/react-jianshu/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "blog",
3 | "version": "0.1.0",
4 | "private": true,
5 | "dependencies": {
6 | "@testing-library/jest-dom": "^4.2.4",
7 | "@testing-library/react": "^9.3.2",
8 | "@testing-library/user-event": "^7.1.2",
9 | "axios": "^0.19.2",
10 | "immutable": "^4.0.0-rc.12",
11 | "react": "^16.13.0",
12 | "react-dom": "^16.13.0",
13 | "react-loadable": "^5.5.0",
14 | "react-redux": "^7.2.0",
15 | "react-router-dom": "^5.1.2",
16 | "react-scripts": "3.4.0",
17 | "react-transition-group": "^4.3.0",
18 | "redux": "^4.0.5",
19 | "redux-thunk": "^2.3.0",
20 | "styled-components": "^5.0.1"
21 | },
22 | "scripts": {
23 | "start": "react-scripts start",
24 | "build": "react-scripts build",
25 | "test": "react-scripts test",
26 | "eject": "react-scripts eject"
27 | },
28 | "eslintConfig": {
29 | "extends": "react-app"
30 | },
31 | "browserslist": {
32 | "production": [
33 | ">0.2%",
34 | "not dead",
35 | "not op_mini all"
36 | ],
37 | "development": [
38 | "last 1 chrome version",
39 | "last 1 firefox version",
40 | "last 1 safari version"
41 | ]
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/react-jianshu/public/api/detail.json:
--------------------------------------------------------------------------------
1 | {
2 | "success": true,
3 | "data": {
4 | "title": "Redux中间件之redux-thunk使用详解",
5 | "content":"
Redux的核心概念其实很简单:将需要修改的state都存入到store里,发起一个action用来描述发生了什么,用reducers描述action如何改变state tree 。创建store的时候需要传入reducer,真正能改变store中数据的是store.dispatch API。
dispatch一个action之后,到达reducer之前,进行一些额外的操作,就需要用到middleware。你可以利用 Redux middleware 来进行日志记录、创建崩溃报告、调用异步接口或者路由等等。换言之,中间件都是对store.dispatch()的增强
"
6 | }
7 | }
--------------------------------------------------------------------------------
/react-jianshu/public/api/homeList.json:
--------------------------------------------------------------------------------
1 | {
2 | "success": true,
3 | "data": [
4 | {
5 | "id": 5,
6 | "title": "我看到了妻子的另一面",
7 | "desc": "父母永远都是孩子最亲近的人,特别是妈妈从怀孕到生孩子这个过程,她们给了孩子生命,同时也时刻守护着孩子们的成长。 绝大多数情况下,妈妈和孩子都是最...",
8 | "imgUrl": "https://upload-images.jianshu.io/upload_images/14805474-d0c2e5243e2c9d41.jpg?imageMogr2/auto-orient/strip|imageView2/1/w/360/h/240"
9 | },
10 | {
11 | "id": 6,
12 | "title": "一个人是否值得交往,看这四点就够了",
13 | "desc": "有人说:“不必把太多人请进生命里,若他们走进不了你的内心,就只会把你的生命搅扰得拥挤不堪。” 朋友不必多,贵在能知心。珍贵的情谊,要留给最值得结...",
14 | "imgUrl": "https://upload-images.jianshu.io/upload_images/14805474-d0c2e5243e2c9d41.jpg?imageMogr2/auto-orient/strip|imageView2/1/w/360/h/240"
15 | },
16 | {
17 | "id": 7,
18 | "title": "“因为10个口罩,我看到了妻子的另一面,终止了两年的婚外恋”",
19 | "desc": "01 作家詹迪·尼尔森曾说:“遇见灵魂伴侣的感觉,就好像是走进一座你曾经住过的房子里——你认识那些家具,认识墙上的画,架上的书,抽屉里的东西:如...",
20 | "imgUrl": "https://upload-images.jianshu.io/upload_images/14805474-d0c2e5243e2c9d41.jpg?imageMogr2/auto-orient/strip|imageView2/1/w/360/h/240"
21 | },
22 | {
23 | "id": 8,
24 | "title": "“因为10个口罩,我看到了妻子的另一面,终止了两年的婚外恋”",
25 | "desc": "01 作家詹迪·尼尔森曾说:“遇见灵魂伴侣的感觉,就好像是走进一座你曾经住过的房子里——你认识那些家具,认识墙上的画,架上的书,抽屉里的东西:如...",
26 | "imgUrl": "https://upload-images.jianshu.io/upload_images/14805474-d0c2e5243e2c9d41.jpg?imageMogr2/auto-orient/strip|imageView2/1/w/360/h/240"
27 | }
28 | ]
29 | }
--------------------------------------------------------------------------------
/react-jianshu/public/api/login.json:
--------------------------------------------------------------------------------
1 | {
2 | "success": true,
3 | "data": true
4 | }
--------------------------------------------------------------------------------
/react-jianshu/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dmCas/React-study/19cc2c81b77f0850c1e029050b260447c849624d/react-jianshu/public/favicon.ico
--------------------------------------------------------------------------------
/react-jianshu/public/logo192.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dmCas/React-study/19cc2c81b77f0850c1e029050b260447c849624d/react-jianshu/public/logo192.png
--------------------------------------------------------------------------------
/react-jianshu/public/logo512.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dmCas/React-study/19cc2c81b77f0850c1e029050b260447c849624d/react-jianshu/public/logo512.png
--------------------------------------------------------------------------------
/react-jianshu/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 | "src": "logo192.png",
12 | "type": "image/png",
13 | "sizes": "192x192"
14 | },
15 | {
16 | "src": "logo512.png",
17 | "type": "image/png",
18 | "sizes": "512x512"
19 | }
20 | ],
21 | "start_url": ".",
22 | "display": "standalone",
23 | "theme_color": "#000000",
24 | "background_color": "#ffffff"
25 | }
26 |
--------------------------------------------------------------------------------
/react-jianshu/public/robots.txt:
--------------------------------------------------------------------------------
1 | # https://www.robotstxt.org/robotstxt.html
2 | User-agent: *
3 | Disallow:
4 |
--------------------------------------------------------------------------------
/react-jianshu/src/App.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import Header from './common/header'
3 | import store from './store'
4 | import { Provider } from 'react-redux'
5 | import { BrowserRouter, Route } from 'react-router-dom'
6 | import Home from './pages/home'
7 | import Detail from './pages/detail/loadable'
8 | import Login from './pages/login'
9 | import Write from './pages/write'
10 |
11 | function App() {
12 | return (
13 |
14 |
15 |
16 |
17 | {/* 内容都受BrowserHistory控制 */}
18 |
19 |
20 | {/* ?不影响路由匹配 */}
21 | {/* 与List.js组件Link匹配 */}
22 |
23 | {/* */}
24 |
25 |
26 |
27 |
28 |
29 | );
30 | }
31 |
32 | export default App;
33 |
--------------------------------------------------------------------------------
/react-jianshu/src/common/header/store/actionCreator.js:
--------------------------------------------------------------------------------
1 | import * as types from './actionTypes'
2 | export const searchFocus = () => ({
3 | type : types.SEARCH_FOCUS
4 | })
5 |
6 | export const searchBlur = () => ({
7 | type : types.SEARCH_BLUR
8 | })
--------------------------------------------------------------------------------
/react-jianshu/src/common/header/store/actionTypes.js:
--------------------------------------------------------------------------------
1 | export const SEARCH_FOCUS = 'search_focus'
2 | export const SEARCH_BLUR = 'search_blur'
--------------------------------------------------------------------------------
/react-jianshu/src/common/header/store/index.js:
--------------------------------------------------------------------------------
1 | import reducer from './reducer'
2 | import * as actionCreator from './actionCreator'
3 | import * as actionTypes from './actionTypes'
4 |
5 | export { reducer,actionCreator,actionTypes }
--------------------------------------------------------------------------------
/react-jianshu/src/common/header/store/reducer.js:
--------------------------------------------------------------------------------
1 | import * as types from './actionTypes'
2 | import { fromJS } from 'immutable'
3 |
4 | const defaultState = fromJS({
5 | focused: false
6 | });
7 |
8 | export default (state = defaultState, action) => {
9 | switch(action.type){
10 | case types.SEARCH_FOCUS:
11 | // immutable对象的set方法,会结合之前immutable对象的值和设置的值,返回一个全新的对象
12 | return state.set('focused', true)
13 | // return {
14 | // focused: true
15 | // };
16 | case types.SEARCH_BLUR:
17 | return state.set('focused', false)
18 | // return {
19 | // focused: false
20 | // };
21 |
22 | // if(action.type === 'search_focus'){
23 | // return {
24 | // focused: true
25 | // }
26 | // }
27 | // if(action.type === 'search_blur'){
28 | // return {
29 | // focused: false
30 | // }
31 | // }
32 |
33 | default: return state
34 | }
35 | }
--------------------------------------------------------------------------------
/react-jianshu/src/index.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import ReactDOM from 'react-dom';
3 | import { GlobalStyle } from './style.js';
4 | import { IconGlobalStyle } from './static/icon-font/iconfont'
5 | import App from './App';
6 |
7 | ReactDOM.render(
8 |
13 | , document.getElementById('root'));
14 |
15 |
--------------------------------------------------------------------------------
/react-jianshu/src/pages/detail/index.js:
--------------------------------------------------------------------------------
1 | import React, { Component } from 'react'
2 | import { connect } from 'react-redux'
3 | import { actionCreators } from './store'
4 | import { withRouter } from 'react-router-dom'
5 | import {
6 | DetailWrapper,
7 | Header,
8 | Content
9 | } from './style'
10 | class Detail extends Component {
11 | componentDidMount() {
12 | this.props.getDetail(this.props.match.params.id)
13 | }
14 |
15 | render() {
16 | console.log(this.props.location.search)
17 | return (
18 |
19 |
20 |
21 |
22 |
23 | )
24 | }
25 | }
26 |
27 | const mapState = (state) => ({
28 | title: state.detail.get('title'),
29 | content: state.detail.get('content')
30 | })
31 |
32 | const mapDispatch = (dispatch) => ({
33 | getDetail(id) {
34 | dispatch(actionCreators.getDetail(id))
35 | }
36 | })
37 |
38 | export default connect(mapState, mapDispatch)(withRouter(Detail))
--------------------------------------------------------------------------------
/react-jianshu/src/pages/detail/loadable.js:
--------------------------------------------------------------------------------
1 | import React from 'react'
2 | import Loadable from 'react-loadable'
3 |
4 | const LoadableComponent = Loadable({
5 | loader: () => import('./'),
6 | loading() {
7 | return 正在加载...
8 | }
9 | });
10 |
11 | export default () =>
--------------------------------------------------------------------------------
/react-jianshu/src/pages/detail/store/actionCreators.js:
--------------------------------------------------------------------------------
1 | import axios from 'axios'
2 | import * as constants from './constants'
3 |
4 | const changeDetail = (title, content) => ({
5 | type: constants.CHANGE_DETAIL,
6 | title,
7 | content
8 | })
9 |
10 | export const getDetail = (id) => {
11 | // Vue 写法
12 | // this.$router.push({ path: '/detail', param={}})
13 | return (dispatch) => {
14 | axios.get('/api/detail.json?id='+id).then(res=> {
15 | console.log(res.data.data)
16 | const result = res.data.data
17 | dispatch(changeDetail(result.title, result.content))
18 | })
19 | }
20 | }
--------------------------------------------------------------------------------
/react-jianshu/src/pages/detail/store/constants.js:
--------------------------------------------------------------------------------
1 | export const CHANGE_DETAIL = 'detail/CHANGE_DETAIL'
--------------------------------------------------------------------------------
/react-jianshu/src/pages/detail/store/index.js:
--------------------------------------------------------------------------------
1 | import reducer from './reducer'
2 | import * as actionCreators from './actionCreators'
3 | import * as constants from './constants'
4 |
5 | export { reducer, actionCreators, constants }
--------------------------------------------------------------------------------
/react-jianshu/src/pages/detail/store/reducer.js:
--------------------------------------------------------------------------------
1 | import { fromJS } from 'immutable'
2 | import * as constants from './constants'
3 |
4 | const defaultState = fromJS({
5 | title: '',
6 | content: ''
7 | });
8 |
9 |
10 | export default (state = defaultState, action) => {
11 | switch(action.type){
12 | case constants.CHANGE_DETAIL:
13 | return state.merge({
14 | title: action.title,
15 | content: action.content
16 | })
17 | default:
18 | return state
19 | }
20 | }
--------------------------------------------------------------------------------
/react-jianshu/src/pages/detail/style.js:
--------------------------------------------------------------------------------
1 | import styled from 'styled-components'
2 |
3 | export const DetailWrapper = styled.div`
4 | overflow: hidden;
5 | width: 720px;
6 | margin: 0 auto;
7 | padding-bottom: 100px;
8 | /* background: red; */
9 | `
10 |
11 | export const Header = styled.div`
12 | margin: 40px 0 20px 0;
13 | font-size: 24px;
14 | line-height: 44px;
15 | color: #333;
16 | font-weight: bold;
17 | `
18 |
19 | export const Content = styled.div`
20 | color: #404040;
21 | img{
22 | max-height: 1245px;
23 | max-width: 100%;
24 | margin: 0 auto;
25 | display: block;
26 | }
27 | p{
28 | margin: 25px 0;
29 | color: #2f2f2f;
30 | font-size: 16px;
31 | line-height: 30px;
32 | }
33 | `
--------------------------------------------------------------------------------
/react-jianshu/src/pages/home/components/List.js:
--------------------------------------------------------------------------------
1 | import React, { Component } from 'react'
2 | import { ListItem, ListInfo, LoadMore } from '../style'
3 | import { connect } from 'react-redux'
4 | import { actionCreators } from '../store'
5 | import { Link } from 'react-router-dom'
6 |
7 | class List extends Component {
8 | render() {
9 | const { page } = this.props
10 | return (
11 |
32 | )
33 | }
34 | }
35 |
36 | const mapState = (state) => (
37 | {
38 | articleList: state.home.get('articleList'),
39 | page: state.home.get('acticlePage')
40 | }
41 | )
42 |
43 | // 加载更多需要ajax接口异步请求
44 | const mapDispatch = (dispatch) => ({
45 | getMoreList(page) {
46 | dispatch(actionCreators.getMoreList(page))
47 | }
48 | })
49 |
50 | export default connect(mapState, mapDispatch)(List)
--------------------------------------------------------------------------------
/react-jianshu/src/pages/home/components/Recommend.js:
--------------------------------------------------------------------------------
1 | import React, { Component } from 'react'
2 | import { RecommendWrapper, RecommendItem } from '../style'
3 | import { connect } from 'react-redux'
4 |
5 | class Recommend extends Component {
6 | render() {
7 | return (
8 |
9 | {
10 | this.props.list.map((item) => {
11 | return (
12 |
13 |
14 |
15 | )
16 | })
17 | }
18 |
19 | )
20 | }
21 | }
22 |
23 | const mapState = (state) => ({
24 | list: state.home.get('recommendList')
25 | })
26 |
27 | export default connect(mapState, null)(Recommend)
--------------------------------------------------------------------------------
/react-jianshu/src/pages/home/components/Topic.js:
--------------------------------------------------------------------------------
1 | import React, { Component } from 'react'
2 | import { connect } from 'react-redux'
3 | import { TopicWrapper, TopicItem } from '../style'
4 |
5 | class Topic extends Component {
6 | render () {
7 | return (
8 |
9 | {
10 | this.props.list.map((item) => {
11 | return (
12 |
13 |
14 | {item.get('title')}
15 |
16 | )
17 | })
18 | }
19 |
20 |
21 | )
22 | }
23 | }
24 |
25 | const mapStateToprops = (state) => ({
26 | list: state.home.get('topicList')
27 | })
28 |
29 | export default connect(mapStateToprops, null)(Topic)
--------------------------------------------------------------------------------
/react-jianshu/src/pages/home/components/Writer.js:
--------------------------------------------------------------------------------
1 | import React, { Component } from 'react'
2 | import { WriterWrapper } from '../style'
3 |
4 |
5 | class Writer extends Component {
6 | render () {
7 | return (
8 | Homework
9 | )
10 | }
11 | }
12 |
13 | export default Writer
--------------------------------------------------------------------------------
/react-jianshu/src/pages/home/store/actionCreators.js:
--------------------------------------------------------------------------------
1 | import axios from 'axios'
2 | import * as constants from './constants'
3 | import { fromJS } from 'immutable'
4 |
5 | const changeHomeData = (result) => ({
6 | type: constants.CHANGE_HOME_DATA,
7 | topicList: result.topicList,
8 | article: result.articleList,
9 | recommendList: result.recommendList
10 | })
11 |
12 | const addHomeList = (articleList, nextPage) => ({
13 | type: constants.ADD_ATRICLE_LIST,
14 | articleList: fromJS(articleList),
15 | nextPage
16 | })
17 |
18 | export const getHomeInfo = () => {
19 | return (dispatch) => {
20 | axios.get('/api/home.json').then((res) => {
21 | const result = res.data.data
22 | const action = changeHomeData(result)
23 | dispatch(action)
24 | })
25 | }
26 | }
27 |
28 | export const getMoreList = (page) => {
29 | return (dispatch) => {
30 | axios.get('/api/homeList.json?page=' + page).then((res) => {
31 | const result = res.data.data
32 | const action = addHomeList(result, page + 1)
33 | dispatch(action)
34 | })
35 | }
36 | }
37 |
38 | export const toggleShow = (show) => ({
39 | type: constants.TOGGLE_SCROLL_TOP,
40 | show: show
41 | })
--------------------------------------------------------------------------------
/react-jianshu/src/pages/home/store/constants.js:
--------------------------------------------------------------------------------
1 | export const CHANGE_HOME_DATA = 'home/CHANGE_HOME_DATA'
2 | export const ADD_ATRICLE_LIST = 'home/ADD_ATRICLE_LIST'
3 | export const TOGGLE_SCROLL_TOP = 'home/TOGGLE_SCROLL_TOP'
--------------------------------------------------------------------------------
/react-jianshu/src/pages/home/store/index.js:
--------------------------------------------------------------------------------
1 | import reducer from './reducer'
2 | import * as actionCreators from './actionCreators'
3 | import * as constants from './constants'
4 |
5 | export { reducer, actionCreators, constants }
--------------------------------------------------------------------------------
/react-jianshu/src/pages/home/store/reducer.js:
--------------------------------------------------------------------------------
1 | import { fromJS } from 'immutable'
2 | import * as constants from './constants'
3 |
4 | const defaultState = fromJS({
5 | topicList: [],
6 | articleList:[],
7 | recommendList: [],
8 | acticlePage: 1,
9 | showScroll: false
10 | });
11 |
12 | const changeHomeData = (state, action) => {
13 | return state.merge({ //把多个对象合并成一个对象
14 | topicList: fromJS(action.topicList),
15 | articleList: fromJS(action.article),
16 | recommendList: fromJS(action.recommendList),
17 | })
18 | }
19 |
20 | const addArticleList = (state, action) => {
21 | return state.merge({
22 | articleList:state.get('articleList').concat(action.articleList),
23 | acticlePage: action.nextPage
24 | })
25 | }
26 |
27 | export default (state = defaultState, action) => {
28 | if(action.type === constants.CHANGE_HOME_DATA){
29 | return changeHomeData(state, action)
30 | }
31 | if(action.type === constants.ADD_ATRICLE_LIST){
32 | return addArticleList(state, action)
33 | // return state.set('articleList', state.get('articleList').concat(action.articleList))
34 | }
35 | if(action.type === constants.TOGGLE_SCROLL_TOP){
36 | return state.set('showScroll' ,action.show)
37 | }
38 | return state
39 | }
--------------------------------------------------------------------------------
/react-jianshu/src/pages/login/index.js:
--------------------------------------------------------------------------------
1 | import React, { Component } from 'react'
2 | // import { actionCreators } from './store'
3 | import { connect } from 'react-redux'
4 | import { actionCreators } from './store'
5 | import { Redirect } from 'react-router-dom'
6 | import {
7 | LoginWrapper,
8 | LoginBox,
9 | Input,
10 | Button
11 | } from './style'
12 |
13 | class Login extends Component {
14 | render () {
15 | const { login } = this.props
16 | console.log(login)
17 | if (!login) {
18 | return (
19 |
20 |
21 | {this.account = input}} />
22 | {this.password = input}}/>
23 |
24 |
25 |
26 | )
27 | }
28 | else {
29 | return
30 | }
31 |
32 | }
33 | }
34 |
35 | const mapState = (state) => ({
36 | login: state.login.get('login')
37 | })
38 |
39 | const mapDispatch = (dispatch) => ({
40 | login_web(accountItem, passwordItem) {
41 | dispatch(actionCreators.login(accountItem.value, passwordItem.value))
42 | }
43 | })
44 |
45 |
46 | export default connect(mapState, mapDispatch)(Login)
--------------------------------------------------------------------------------
/react-jianshu/src/pages/login/store/actionCreators.js:
--------------------------------------------------------------------------------
1 | import axios from 'axios'
2 | import {constants} from '../store'
3 |
4 |
5 | const changeLogin= () => ({
6 | type: constants.CHANGE_LOGIN,
7 | value: true
8 | })
9 |
10 | export const login = (account, password) => {
11 | return (dispatch) => {
12 | axios.get('/api/login.json?account='+ account + '&password=' + password).then(
13 | (res) => {
14 | const result = res.data.data
15 | if (result) {
16 | dispatch(changeLogin())
17 | }else{
18 | alert('登录失败')
19 | }
20 | }
21 | )
22 | }
23 | }
24 |
25 | export const login_off = () => {
26 | return (dispatch) => {
27 | const action = {
28 | type: constants.LOG_OFF,
29 | value: false
30 | }
31 | dispatch(action)
32 | }
33 | }
--------------------------------------------------------------------------------
/react-jianshu/src/pages/login/store/constants.js:
--------------------------------------------------------------------------------
1 | export const CHANGE_LOGIN = 'login/CHANGE_LOGIN'
2 | export const LOG_OFF = 'login/LOG_OFF'
--------------------------------------------------------------------------------
/react-jianshu/src/pages/login/store/index.js:
--------------------------------------------------------------------------------
1 | import reducer from './reducer'
2 | import * as actionCreators from './actionCreators'
3 | import * as constants from './constants'
4 |
5 | export { reducer, actionCreators, constants }
--------------------------------------------------------------------------------
/react-jianshu/src/pages/login/store/reducer.js:
--------------------------------------------------------------------------------
1 | import { fromJS } from 'immutable'
2 | import * as constants from './constants'
3 | // immutable.js
4 | // facebook
5 | // immutable对象
6 |
7 | const defaultState = fromJS({
8 | login: false
9 | })
10 |
11 | export default (state = defaultState, action) => {
12 | switch (action.type) {
13 | case constants.CHANGE_LOGIN:
14 | return state.set('login', action.value)
15 | case constants.LOG_OFF:
16 | return state.set('login', action.value)
17 | default:
18 | return state
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/react-jianshu/src/pages/login/style.js:
--------------------------------------------------------------------------------
1 | import styled from 'styled-components'
2 |
3 | export const LoginWrapper = styled.div`
4 | position: absolute;
5 | left: 0;
6 | right: 0;
7 | bottom: 0;
8 | top: 56px;
9 | background: #eee;
10 |
11 | `
12 |
13 | export const LoginBox = styled.div`
14 | padding-top: 80px;
15 | width: 400px;
16 | height: 320px;
17 | margin: 50px auto;
18 | background: #fff;
19 | box-shadow: 0 0 8px rgba(0, 0, 0, .1);
20 | box-sizing: border-box;
21 | `
22 |
23 | export const Input = styled.input`
24 | display: block;
25 | width: 200px;
26 | height: 30px;
27 | line-height: 30px;
28 | color: #777;
29 | margin: 10px auto;
30 | padding: 0 10px;
31 | /* border: 1px solid #000; */
32 | `
33 |
34 | export const Button = styled.div`
35 | display: block;
36 | width: 200px;
37 | height: 30px;
38 | color: #fff;
39 | line-height: 30px;
40 | background: #3194d0;
41 | border-radius: 10px;
42 | margin: 30px auto;
43 | text-align: center;
44 | `
--------------------------------------------------------------------------------
/react-jianshu/src/pages/write/index.js:
--------------------------------------------------------------------------------
1 | import React, { Component } from 'react'
2 | // import { actionCreators } from './store'
3 | import { connect } from 'react-redux'
4 | import { Redirect } from 'react-router-dom'
5 |
6 |
7 | class Write extends Component {
8 | render () {
9 | const { loginState } = this.props
10 | if (loginState) {
11 | return (
12 | 写文章页面
13 | )
14 | }
15 | else {
16 | return
17 | }
18 |
19 | }
20 | }
21 |
22 | const mapState = (state) => ({
23 | loginState: state.login.get('login')
24 | })
25 |
26 |
27 | export default connect(mapState, null)(Write)
--------------------------------------------------------------------------------
/react-jianshu/src/static/icon-font/iconfont.eot:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dmCas/React-study/19cc2c81b77f0850c1e029050b260447c849624d/react-jianshu/src/static/icon-font/iconfont.eot
--------------------------------------------------------------------------------
/react-jianshu/src/static/icon-font/iconfont.json:
--------------------------------------------------------------------------------
1 | {
2 | "id": "1688023",
3 | "name": "jianshu",
4 | "font_family": "iconfont",
5 | "css_prefix_text": "icon",
6 | "description": "这是简书icon仓库",
7 | "glyphs": [
8 | {
9 | "icon_id": "2356808",
10 | "name": "毛笔",
11 | "font_class": "maobi",
12 | "unicode": "e62e",
13 | "unicode_decimal": 58926
14 | },
15 | {
16 | "icon_id": "8158665",
17 | "name": "Aa",
18 | "font_class": "Aa",
19 | "unicode": "e698",
20 | "unicode_decimal": 59032
21 | },
22 | {
23 | "icon_id": "8546046",
24 | "name": "放大镜",
25 | "font_class": "fangdajing",
26 | "unicode": "e63f",
27 | "unicode_decimal": 58943
28 | }
29 | ]
30 | }
31 |
--------------------------------------------------------------------------------
/react-jianshu/src/static/icon-font/iconfont.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dmCas/React-study/19cc2c81b77f0850c1e029050b260447c849624d/react-jianshu/src/static/icon-font/iconfont.ttf
--------------------------------------------------------------------------------
/react-jianshu/src/static/icon-font/iconfont.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dmCas/React-study/19cc2c81b77f0850c1e029050b260447c849624d/react-jianshu/src/static/icon-font/iconfont.woff
--------------------------------------------------------------------------------
/react-jianshu/src/static/icon-font/iconfont.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dmCas/React-study/19cc2c81b77f0850c1e029050b260447c849624d/react-jianshu/src/static/icon-font/iconfont.woff2
--------------------------------------------------------------------------------
/react-jianshu/src/static/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dmCas/React-study/19cc2c81b77f0850c1e029050b260447c849624d/react-jianshu/src/static/logo.png
--------------------------------------------------------------------------------
/react-jianshu/src/store/index.js:
--------------------------------------------------------------------------------
1 | import { createStore, compose, applyMiddleware } from 'redux'
2 | import reducer from './reducer'
3 | import thunk from 'redux-thunk'
4 |
5 | const componentEnhanders = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose;
6 |
7 | const enhancer = componentEnhanders(
8 | applyMiddleware(thunk)
9 | // applyMiddleware(sagaMiddleware)
10 | )
11 | const store = createStore(reducer, enhancer)
12 |
13 | export default store;
--------------------------------------------------------------------------------
/react-jianshu/src/store/reducer.js:
--------------------------------------------------------------------------------
1 | import { combineReducers } from 'redux'
2 | import { reducer as headerReducer } from '../common/header/store'
3 | import { reducer as homeReducer } from '../pages/home/store'
4 | import { reducer as detailReducer } from '../pages/detail/store'
5 | import { reducer as loginReducer } from '../pages/login/store'
6 | // 合并小的reducer
7 | const reducer = combineReducers({
8 | header: headerReducer,
9 | home: homeReducer,
10 | detail: detailReducer,
11 | login: loginReducer
12 | })
13 |
14 | export default reducer
--------------------------------------------------------------------------------
/react-jianshu/src/style.js:
--------------------------------------------------------------------------------
1 | import { createGlobalStyle } from 'styled-components'
2 |
3 | export const GlobalStyle = createGlobalStyle`
4 | body {
5 | margin: 0;
6 | font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen',
7 | 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue',
8 | sans-serif;
9 | -webkit-font-smoothing: antialiased;
10 | -moz-osx-font-smoothing: grayscale;
11 | }
12 |
13 | code {
14 | font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New',
15 | monospace;
16 | }
17 |
18 | html, body, div, span, applet, object, iframe,
19 | h1, h2, h3, h4, h5, h6, p, blockquote, pre,
20 | a, abbr, acronym, address, big, cite, code,
21 | del, dfn, em, img, ins, kbd, q, s, samp,
22 | small, strike, strong, sub, sup, tt, var,
23 | b, u, i, center,
24 | dl, dt, dd, ol, ul, li,
25 | fieldset, form, label, legend,
26 | table, caption, tbody, tfoot, thead, tr, th, td,
27 | article, aside, canvas, details, embed,
28 | figure, figcaption, footer, header, hgroup,
29 | menu, nav, output, ruby, section, summary,
30 | time, mark, audio, video {
31 | margin: 0;
32 | padding: 0;
33 | border: 0;
34 | font-size: 100%;
35 | font: inherit;
36 | vertical-align: baseline;
37 | color: #000;
38 | }
39 | /* HTML5 display-role reset for older browsers */
40 | article, aside, details, figcaption, figure,
41 | footer, header, hgroup, menu, nav, section {
42 | display: block;
43 | }
44 | body {
45 | line-height: 1;
46 | }
47 | ol, ul {
48 | list-style: none;
49 | }
50 | blockquote, q {
51 | quotes: none;
52 | }
53 | blockquote:before, blockquote:after,
54 | q:before, q:after {
55 | content: '';
56 | content: none;
57 | }
58 | table {
59 | border-collapse: collapse;
60 | border-spacing: 0;
61 | }
62 | `
63 |
--------------------------------------------------------------------------------
/react-jianshu/加载更多.md:
--------------------------------------------------------------------------------
1 | ```
2 | {
3 | this.props.showScroll ? 回到顶部 : null
4 | }
5 | componentDidMount () {
6 | this.props.changeHomeData()
7 | this.bindEvents()
8 | }
9 |
10 | bindEvents(){
11 | window.addEventListener('scroll', this.props.changeScrollTopShow)
12 | }
13 |
14 | handleScrollTop () {
15 | window.scrollTo(0,0)
16 | }
17 | ```
18 |
19 | >因为是绑定到window上的,因此在组件卸载(跳转到其它页面的时候需要移除该事件)
20 | componentWillMount() {
21 | window.removeEventListener('scroll', this.props.changeScrollTopShow)
22 | }
23 |
--------------------------------------------------------------------------------
/react-react-redux/.gitignore:
--------------------------------------------------------------------------------
1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
2 |
3 | # dependencies
4 | /node_modules
5 | /.pnp
6 | .pnp.js
7 |
8 | # testing
9 | /coverage
10 |
11 | # production
12 | /build
13 |
14 | # misc
15 | .DS_Store
16 | .env.local
17 | .env.development.local
18 | .env.test.local
19 | .env.production.local
20 |
21 | npm-debug.log*
22 | yarn-debug.log*
23 | yarn-error.log*
24 |
--------------------------------------------------------------------------------
/react-react-redux/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "react-react-redux",
3 | "version": "0.1.0",
4 | "private": true,
5 | "dependencies": {
6 | "@testing-library/jest-dom": "^4.2.4",
7 | "@testing-library/react": "^9.3.2",
8 | "@testing-library/user-event": "^7.1.2",
9 | "react": "^16.13.0",
10 | "react-dom": "^16.13.0",
11 | "react-redux": "^7.2.0",
12 | "react-scripts": "3.4.0"
13 | },
14 | "scripts": {
15 | "start": "react-scripts start",
16 | "build": "react-scripts build",
17 | "test": "react-scripts test",
18 | "eject": "react-scripts eject"
19 | },
20 | "eslintConfig": {
21 | "extends": "react-app"
22 | },
23 | "browserslist": {
24 | "production": [
25 | ">0.2%",
26 | "not dead",
27 | "not op_mini all"
28 | ],
29 | "development": [
30 | "last 1 chrome version",
31 | "last 1 firefox version",
32 | "last 1 safari version"
33 | ]
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/react-react-redux/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dmCas/React-study/19cc2c81b77f0850c1e029050b260447c849624d/react-react-redux/public/favicon.ico
--------------------------------------------------------------------------------
/react-react-redux/public/logo192.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dmCas/React-study/19cc2c81b77f0850c1e029050b260447c849624d/react-react-redux/public/logo192.png
--------------------------------------------------------------------------------
/react-react-redux/public/logo512.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dmCas/React-study/19cc2c81b77f0850c1e029050b260447c849624d/react-react-redux/public/logo512.png
--------------------------------------------------------------------------------
/react-react-redux/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 | "src": "logo192.png",
12 | "type": "image/png",
13 | "sizes": "192x192"
14 | },
15 | {
16 | "src": "logo512.png",
17 | "type": "image/png",
18 | "sizes": "512x512"
19 | }
20 | ],
21 | "start_url": ".",
22 | "display": "standalone",
23 | "theme_color": "#000000",
24 | "background_color": "#ffffff"
25 | }
26 |
--------------------------------------------------------------------------------
/react-react-redux/public/robots.txt:
--------------------------------------------------------------------------------
1 | # https://www.robotstxt.org/robotstxt.html
2 | User-agent: *
3 | Disallow:
4 |
--------------------------------------------------------------------------------
/react-react-redux/src/TodoList.js:
--------------------------------------------------------------------------------
1 | import React, { Component } from 'react'
2 | // import store from './store'
3 | import { connect } from 'react-redux'
4 |
5 | class TodoList extends Component {
6 | // constructor(props) {
7 | // super(props)
8 | // this.state = store.getState()
9 | // }
10 |
11 | // handleInputChange(e) {
12 | // //用这个值替换store里inputValue的值
13 | // console.log(e.target.value)
14 | // const action =
15 | // this.props.dispatch(action)
16 | // }
17 |
18 | render () {
19 | return (
20 |
21 |
22 |
23 |
24 |
25 |
26 | - {this.props.list}
27 |
28 |
29 | )
30 | }
31 | }
32 |
33 | // 遍历state里面的所有数据给到props
34 | const mapStateToProps = (state) => {
35 | return {
36 | inputValue: state.inputValue,
37 | list: state.list
38 | }
39 | }
40 |
41 | const mapDispatchToProps = (dispatch) => { // 把store.dispatch 挂载到props上
42 | return {
43 | changeInputValue (e) {
44 | const action = {
45 | type : 'change_input_value',
46 | value: e.target.value
47 | }
48 | console.log(action)
49 | // const action = getChangeInputAction(e.target.value)
50 | dispatch(action)
51 | }
52 | }
53 | }
54 |
55 | // connect 是连接
56 | // TodoList 和 store 做连接
57 | // mapStateToProps 的参数就是 store里面的数据 该方法会帮助我们把store映射到props
58 |
59 | export default connect(mapStateToProps, mapDispatchToProps)(TodoList)
--------------------------------------------------------------------------------
/react-react-redux/src/index.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import ReactDOM from 'react-dom';
3 | import TodoList from './TodoList'
4 | import { Provider } from 'react-redux'
5 | import store from './store'
6 |
7 | // Provider 连接器连接了store, 那么Provider里面的所有的组件都具备了使用store里面的内容的权力
8 | const App = (
9 |
10 |
11 |
12 | )
13 |
14 | ReactDOM.render(App, document.getElementById('root'));
15 |
16 |
--------------------------------------------------------------------------------
/react-react-redux/src/store/index.js:
--------------------------------------------------------------------------------
1 | import { createStore } from 'redux'
2 | import reducer from './reducer'
3 |
4 | const store = createStore(reducer)
5 |
6 | export default store
--------------------------------------------------------------------------------
/react-react-redux/src/store/reducer.js:
--------------------------------------------------------------------------------
1 | const defaultState = {
2 | inputValue: '123',
3 | list: [1],
4 | data:[]
5 | }
6 |
7 | export default (state = defaultState, action) => {
8 | if(action.type === 'change_input_value'){
9 | const newState = JSON.parse(JSON.stringify(state))
10 | newState.list.push(action.value)
11 | console.log(newState.list)
12 | return newState // reducer 有一个限制, 可以接收state, 但是绝对不能修改state
13 | }
14 | return state
15 | }
--------------------------------------------------------------------------------
/react-redux/.gitignore:
--------------------------------------------------------------------------------
1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
2 |
3 | # dependencies
4 | /node_modules
5 | /.pnp
6 | .pnp.js
7 |
8 | # testing
9 | /coverage
10 |
11 | # production
12 | /build
13 |
14 | # misc
15 | .DS_Store
16 | .env.local
17 | .env.development.local
18 | .env.test.local
19 | .env.production.local
20 |
21 | npm-debug.log*
22 | yarn-debug.log*
23 | yarn-error.log*
24 |
--------------------------------------------------------------------------------
/react-redux/README.md:
--------------------------------------------------------------------------------
1 | # reducer 有一个限制, 可以接收state, 但是绝对不能修改state
2 |
3 | # redux
4 | 1. 用react 实现todolist
5 | 2. 加入reudx
6 | 3. actionTypes 整合
7 | 4. 使用actionCreator 统一创建 action
8 |
9 | # 总结 redux的设计使用原则
10 | 1. store 是唯一的
11 | 2. 只有store能改变自己的内容
12 | 3. reducer 是一个纯函数
13 |
14 | # redux中的核心API
15 | 1. createStore 创建store
16 | 2. store.dispatch 派发action
17 | 3. store.getState 获取store里面所有的数据
18 | 4. store.subscribe 订阅store数据的改变
19 |
20 | # UI组件与容器组件
21 | UI组件: 渲染页面 -> 一般定义成无状态组件 function
22 | 容器组件: 逻辑操作
23 |
24 | # 无状态组件
25 |
26 | # Redux中发送异步请求获取数据
27 |
28 | # redux-thunk ajax数据请求
29 |
30 | # 什么是 Redux 中间件
31 |
32 | # redux-saga 中间件 ajax数据请求
33 |
34 | # react-redux
35 |
36 |
--------------------------------------------------------------------------------
/react-redux/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "react-redux",
3 | "version": "0.1.0",
4 | "private": true,
5 | "dependencies": {
6 | "@testing-library/jest-dom": "^4.2.4",
7 | "@testing-library/react": "^9.3.2",
8 | "@testing-library/user-event": "^7.1.2",
9 | "antd": "^4.0.2",
10 | "axios": "^0.19.2",
11 | "react": "^16.13.0",
12 | "react-dom": "^16.13.0",
13 | "react-scripts": "3.4.0",
14 | "redux": "^4.0.5",
15 | "redux-saga": "^1.1.3",
16 | "redux-thunk": "^2.3.0",
17 | "save": "^2.4.0"
18 | },
19 | "scripts": {
20 | "start": "react-scripts start",
21 | "build": "react-scripts build",
22 | "test": "react-scripts test",
23 | "eject": "react-scripts eject"
24 | },
25 | "eslintConfig": {
26 | "extends": "react-app"
27 | },
28 | "browserslist": {
29 | "production": [
30 | ">0.2%",
31 | "not dead",
32 | "not op_mini all"
33 | ],
34 | "development": [
35 | "last 1 chrome version",
36 | "last 1 firefox version",
37 | "last 1 safari version"
38 | ]
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/react-redux/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dmCas/React-study/19cc2c81b77f0850c1e029050b260447c849624d/react-redux/public/favicon.ico
--------------------------------------------------------------------------------
/react-redux/public/logo192.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dmCas/React-study/19cc2c81b77f0850c1e029050b260447c849624d/react-redux/public/logo192.png
--------------------------------------------------------------------------------
/react-redux/public/logo512.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dmCas/React-study/19cc2c81b77f0850c1e029050b260447c849624d/react-redux/public/logo512.png
--------------------------------------------------------------------------------
/react-redux/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 | "src": "logo192.png",
12 | "type": "image/png",
13 | "sizes": "192x192"
14 | },
15 | {
16 | "src": "logo512.png",
17 | "type": "image/png",
18 | "sizes": "512x512"
19 | }
20 | ],
21 | "start_url": ".",
22 | "display": "standalone",
23 | "theme_color": "#000000",
24 | "background_color": "#ffffff"
25 | }
26 |
--------------------------------------------------------------------------------
/react-redux/public/robots.txt:
--------------------------------------------------------------------------------
1 | # https://www.robotstxt.org/robotstxt.html
2 | User-agent: *
3 | Disallow:
4 |
--------------------------------------------------------------------------------
/react-redux/redux 原理图.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dmCas/React-study/19cc2c81b77f0850c1e029050b260447c849624d/react-redux/redux 原理图.jpg
--------------------------------------------------------------------------------
/react-redux/src/App.css:
--------------------------------------------------------------------------------
1 | .App {
2 | text-align: center;
3 | }
4 |
5 | .App-logo {
6 | height: 40vmin;
7 | pointer-events: none;
8 | }
9 |
10 | @media (prefers-reduced-motion: no-preference) {
11 | .App-logo {
12 | animation: App-logo-spin infinite 20s linear;
13 | }
14 | }
15 |
16 | .App-header {
17 | background-color: #282c34;
18 | min-height: 100vh;
19 | display: flex;
20 | flex-direction: column;
21 | align-items: center;
22 | justify-content: center;
23 | font-size: calc(10px + 2vmin);
24 | color: white;
25 | }
26 |
27 | .App-link {
28 | color: #61dafb;
29 | }
30 |
31 | @keyframes App-logo-spin {
32 | from {
33 | transform: rotate(0deg);
34 | }
35 | to {
36 | transform: rotate(360deg);
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/react-redux/src/App.test.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { render } from '@testing-library/react';
3 | import App from './App';
4 |
5 | test('renders learn react link', () => {
6 | const { getByText } = render();
7 | const linkElement = getByText(/learn react/i);
8 | expect(linkElement).toBeInTheDocument();
9 | });
10 |
--------------------------------------------------------------------------------
/react-redux/src/TodoListUI.js:
--------------------------------------------------------------------------------
1 | import React, { Component } from 'react'
2 | import { Input, Button, List} from 'antd'
3 |
4 | // class TodoListUI extends Component {
5 | // render() {
6 | // return (
7 | //
8 | //
9 | //
11 | //
12 | //
13 | //
18 | // (
19 | // this.props.handleItemDelete(index)
20 | // )}>
21 | // {item}
22 | // }
23 | // />
24 | //
25 | // )
26 | // }
27 | // }
28 |
29 | const TodoListUI = (props) => {
30 | return (
31 |
32 |
33 |
35 |
36 |
37 |
42 | (
43 | props.handleItemDelete(index)
44 | )}>
45 | {item}
46 | }
47 | />
48 |
49 | )
50 | }
51 |
52 | export default TodoListUI
--------------------------------------------------------------------------------
/react-redux/src/assets/list.json:
--------------------------------------------------------------------------------
1 | {
2 | "data": ["hello", "Tom", "Jerry"]
3 | }
--------------------------------------------------------------------------------
/react-redux/src/index.css:
--------------------------------------------------------------------------------
1 | body {
2 | margin: 0;
3 | font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen',
4 | 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue',
5 | sans-serif;
6 | -webkit-font-smoothing: antialiased;
7 | -moz-osx-font-smoothing: grayscale;
8 | }
9 |
10 | code {
11 | font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New',
12 | monospace;
13 | }
14 |
--------------------------------------------------------------------------------
/react-redux/src/index.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import ReactDOM from 'react-dom';
3 | import TodoList from './TodoList';
4 | import * as serviceWorker from './serviceWorker';
5 |
6 | ReactDOM.render(, document.getElementById('root'));
7 |
8 | // If you want your app to work offline and load faster, you can change
9 | // unregister() to register() below. Note this comes with some pitfalls.
10 | // Learn more about service workers: https://bit.ly/CRA-PWA
11 | serviceWorker.unregister();
12 |
--------------------------------------------------------------------------------
/react-redux/src/setupTests.js:
--------------------------------------------------------------------------------
1 | // jest-dom adds custom jest matchers for asserting on DOM nodes.
2 | // allows you to do things like:
3 | // expect(element).toHaveTextContent(/react/i)
4 | // learn more: https://github.com/testing-library/jest-dom
5 | import '@testing-library/jest-dom/extend-expect';
6 |
--------------------------------------------------------------------------------
/react-redux/src/store/actionCreators.js:
--------------------------------------------------------------------------------
1 | import { CHANGE_INPUT_VALUE, ADD_TODO_LIST, DELETE_TODO_ITEM, INIT_LIST_ACTION, GET_INIT_LIST } from './actionTypes'
2 | import axios from 'axios'
3 |
4 | export const getInputChangeAction = (value) => ({
5 | type: CHANGE_INPUT_VALUE,
6 | value
7 | })
8 |
9 | export const getAddAction = () => ({
10 | type: ADD_TODO_LIST
11 | })
12 |
13 | export const getDeleteItemAction = (index) => ({
14 | type: DELETE_TODO_ITEM,
15 | index
16 | })
17 |
18 | export const initListAction = (data) => ({
19 | type: INIT_LIST_ACTION,
20 | data
21 | })
22 |
23 | // redux thunk
24 | // export const getTodoList = () => {
25 | // return (dispatch) => {
26 | // axios.get('http://musicapi.leanapp.cn/comment/music?id=186016&limit=1').then(
27 | // (res) => {
28 | // const data = res.data
29 | // const action = initListAction(Object.keys(data.hotComments[0]))
30 | // // store.dispatch(action)
31 | // console.log(action)
32 | // dispatch(action)
33 | // }
34 | // )
35 | // }
36 | // }
37 |
38 | export const getInitList = () => ({
39 | type: GET_INIT_LIST
40 | })
--------------------------------------------------------------------------------
/react-redux/src/store/actionTypes.js:
--------------------------------------------------------------------------------
1 | export const CHANGE_INPUT_VALUE = 'change_input_value'
2 | export const ADD_TODO_LIST = 'add_todo_list'
3 | export const DELETE_TODO_ITEM = 'delete_todo_item'
4 | export const INIT_LIST_ACTION = 'init_list_action'
5 | export const GET_INIT_LIST = 'get_init_list'
6 |
--------------------------------------------------------------------------------
/react-redux/src/store/index.js:
--------------------------------------------------------------------------------
1 | import { createStore, applyMiddleware, compose } from 'redux'
2 | import reducer from './reducer'
3 | import thunk from 'redux-thunk'
4 | import createSagaMiddleware from 'redux-saga'
5 | import todoSagas from './sagas'
6 |
7 | const sagaMiddleware = createSagaMiddleware()
8 |
9 | const componentEnhanders =
10 | window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ ?
11 | window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ ({
12 | }) : compose;
13 |
14 | const enhancer = componentEnhanders(
15 | // applyMiddleware(thunk)
16 | applyMiddleware(sagaMiddleware)
17 | )
18 |
19 | const store = createStore(
20 | reducer,
21 | enhancer
22 | )
23 |
24 | sagaMiddleware.run(todoSagas)
25 |
26 | //store默认状态
27 | // store = {
28 | // inputValue: '123',
29 | // list: []
30 | // }
31 | // 经过逻辑操作
32 | // store将自己的值变为newState -> store能改变自己的内容
33 |
34 | export default store;
--------------------------------------------------------------------------------
/react-redux/src/store/reducer.js:
--------------------------------------------------------------------------------
1 | import {CHANGE_INPUT_VALUE, ADD_TODO_LIST, DELETE_TODO_ITEM, INIT_LIST_ACTION } from './actionTypes.js'
2 |
3 | const defaultState = {
4 | inputValue: '123',
5 | list: [],
6 | data:[]
7 | }
8 |
9 | // state 指的是 stroe里面上一次存储的数据
10 | // 纯函数指的是,给定固定的输入,就一定会有固定的输出,而不会有任何副作用
11 | export default (state = defaultState, action) => {
12 | if(action.type === CHANGE_INPUT_VALUE){
13 | const newState = JSON.parse(JSON.stringify(state))
14 | newState.inputValue = action.value
15 | return newState // reducer 有一个限制, 可以接收state, 但是绝对不能修改state
16 | }
17 | if(action.type === ADD_TODO_LIST){
18 | const newState = JSON.parse(JSON.stringify(state))
19 | // console.log(newState.inputValue)
20 | if(newState.inputValue===''){
21 | return newState
22 | }
23 | newState.list.push(newState.inputValue)
24 | // console.log(newState.list)
25 | newState.inputValue = ''
26 | return newState
27 | }
28 | if(action.type === DELETE_TODO_ITEM ){
29 | const newState = JSON.parse(JSON.stringify(state))
30 | newState.list.splice(action.index,1)
31 | return newState
32 | }
33 | if(action.type === INIT_LIST_ACTION){
34 | const newState = JSON.parse(JSON.stringify(state))
35 | newState.list = action.data
36 | return newState
37 | }
38 | // console.log(state, action)
39 | return state
40 | }
--------------------------------------------------------------------------------
/react-redux/src/store/sagas.js:
--------------------------------------------------------------------------------
1 | import { takeEvery, put } from 'redux-saga/effects'
2 | import { GET_INIT_LIST } from './actionTypes'
3 | import { initListAction } from './actionCreators'
4 | import axios from 'axios'
5 |
6 | function* getInitList() {
7 | try{
8 | const res = yield axios.get('http://musicapi.leanapp.cn/comment/music?id=186016&limit=1')
9 | const action = initListAction(Object.keys(res.data.hotComments[0]))
10 | yield put(action)
11 | } catch(e){
12 | console.log('网络请求失败')
13 | }
14 |
15 | // axios.get('http://musicapi.leanapp.cn/comment/music?id=186016&limit=1').then(
16 | // (res) => {
17 | // const data = res.data
18 | // const action = initListAction(Object.keys(data.hotComments[0]))
19 | // console.log(action)
20 |
21 | // }
22 | // )
23 | }
24 |
25 | function* mySaga() { // sagas 必须要是 generator函数
26 | yield takeEvery(GET_INIT_LIST, getInitList);
27 | }
28 |
29 | export default mySaga;
--------------------------------------------------------------------------------
/react-router-antd/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "react-router-antd",
3 | "version": "0.1.0",
4 | "private": true,
5 | "dependencies": {
6 | "@testing-library/jest-dom": "^4.2.4",
7 | "@testing-library/react": "^9.3.2",
8 | "@testing-library/user-event": "^7.1.2",
9 | "antd": "^4.0.0",
10 | "react": "^16.13.0",
11 | "react-dom": "^16.13.0",
12 | "react-router-dom": "^5.1.2",
13 | "react-scripts": "3.4.0"
14 | },
15 | "scripts": {
16 | "start": "react-scripts start",
17 | "build": "react-scripts build",
18 | "test": "react-scripts test",
19 | "eject": "react-scripts eject"
20 | },
21 | "eslintConfig": {
22 | "extends": "react-app"
23 | },
24 | "browserslist": {
25 | "production": [
26 | ">0.2%",
27 | "not dead",
28 | "not op_mini all"
29 | ],
30 | "development": [
31 | "last 1 chrome version",
32 | "last 1 firefox version",
33 | "last 1 safari version"
34 | ]
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/react-router-antd/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dmCas/React-study/19cc2c81b77f0850c1e029050b260447c849624d/react-router-antd/public/favicon.ico
--------------------------------------------------------------------------------
/react-router-antd/public/logo192.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dmCas/React-study/19cc2c81b77f0850c1e029050b260447c849624d/react-router-antd/public/logo192.png
--------------------------------------------------------------------------------
/react-router-antd/public/logo512.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dmCas/React-study/19cc2c81b77f0850c1e029050b260447c849624d/react-router-antd/public/logo512.png
--------------------------------------------------------------------------------
/react-router-antd/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 | "src": "logo192.png",
12 | "type": "image/png",
13 | "sizes": "192x192"
14 | },
15 | {
16 | "src": "logo512.png",
17 | "type": "image/png",
18 | "sizes": "512x512"
19 | }
20 | ],
21 | "start_url": ".",
22 | "display": "standalone",
23 | "theme_color": "#000000",
24 | "background_color": "#ffffff"
25 | }
26 |
--------------------------------------------------------------------------------
/react-router-antd/public/robots.txt:
--------------------------------------------------------------------------------
1 | # https://www.robotstxt.org/robotstxt.html
2 | User-agent: *
3 | Disallow:
4 |
--------------------------------------------------------------------------------
/react-router-antd/src/App.css:
--------------------------------------------------------------------------------
1 | .App {
2 | text-align: center;
3 | }
4 |
5 | .App-logo {
6 | height: 40vmin;
7 | pointer-events: none;
8 | }
9 |
10 | @media (prefers-reduced-motion: no-preference) {
11 | .App-logo {
12 | animation: App-logo-spin infinite 20s linear;
13 | }
14 | }
15 |
16 | .App-header {
17 | background-color: #282c34;
18 | min-height: 100vh;
19 | display: flex;
20 | flex-direction: column;
21 | align-items: center;
22 | justify-content: center;
23 | font-size: calc(10px + 2vmin);
24 | color: white;
25 | }
26 |
27 | .App-link {
28 | color: #61dafb;
29 | }
30 |
31 | @keyframes App-logo-spin {
32 | from {
33 | transform: rotate(0deg);
34 | }
35 | to {
36 | transform: rotate(360deg);
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/react-router-antd/src/App.js:
--------------------------------------------------------------------------------
1 | import React from 'react'
2 | import { BrowserRouter as Router, Route, Link } from 'react-router-dom'
3 | import 'antd/dist/antd.css';
4 | import Layout from './pages/Layout'
5 |
6 | function App() {
7 | return (
8 |
9 |
10 |
11 | )
12 | }
13 |
14 | export default App
--------------------------------------------------------------------------------
/react-router-antd/src/App.test.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { render } from '@testing-library/react';
3 | import App from './App';
4 |
5 | test('renders learn react link', () => {
6 | const { getByText } = render();
7 | const linkElement = getByText(/learn react/i);
8 | expect(linkElement).toBeInTheDocument();
9 | });
10 |
--------------------------------------------------------------------------------
/react-router-antd/src/index.css:
--------------------------------------------------------------------------------
1 | body {
2 | margin: 0;
3 | font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen',
4 | 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue',
5 | sans-serif;
6 | -webkit-font-smoothing: antialiased;
7 | -moz-osx-font-smoothing: grayscale;
8 | }
9 |
10 | code {
11 | font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New',
12 | monospace;
13 | }
14 |
--------------------------------------------------------------------------------
/react-router-antd/src/index.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import ReactDOM from 'react-dom';
3 | import './index.css';
4 | import App from './App';
5 | import * as serviceWorker from './serviceWorker';
6 |
7 | ReactDOM.render(, document.getElementById('root'));
8 |
9 | // If you want your app to work offline and load faster, you can change
10 | // unregister() to register() below. Note this comes with some pitfalls.
11 | // Learn more about service workers: https://bit.ly/CRA-PWA
12 | serviceWorker.unregister();
13 |
--------------------------------------------------------------------------------
/react-router-antd/src/setupTests.js:
--------------------------------------------------------------------------------
1 | // jest-dom adds custom jest matchers for asserting on DOM nodes.
2 | // allows you to do things like:
3 | // expect(element).toHaveTextContent(/react/i)
4 | // learn more: https://github.com/testing-library/jest-dom
5 | import '@testing-library/jest-dom/extend-expect';
6 |
--------------------------------------------------------------------------------
/react-router/.gitignore:
--------------------------------------------------------------------------------
1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
2 |
3 | # dependencies
4 | /node_modules
5 | /.pnp
6 | .pnp.js
7 |
8 | # testing
9 | /coverage
10 |
11 | # production
12 | /build
13 |
14 | # misc
15 | .DS_Store
16 | .env.local
17 | .env.development.local
18 | .env.test.local
19 | .env.production.local
20 |
21 | npm-debug.log*
22 | yarn-debug.log*
23 | yarn-error.log*
24 |
--------------------------------------------------------------------------------
/react-router/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "react-router",
3 | "version": "0.1.0",
4 | "private": true,
5 | "dependencies": {
6 | "@testing-library/jest-dom": "^4.2.4",
7 | "@testing-library/react": "^9.3.2",
8 | "@testing-library/user-event": "^7.1.2",
9 | "react": "^16.13.0",
10 | "react-dom": "^16.13.0",
11 | "react-router-dom": "^5.1.2",
12 | "react-scripts": "3.4.0"
13 | },
14 | "scripts": {
15 | "start": "react-scripts start",
16 | "build": "react-scripts build",
17 | "test": "react-scripts test",
18 | "eject": "react-scripts eject"
19 | },
20 | "eslintConfig": {
21 | "extends": "react-app"
22 | },
23 | "browserslist": {
24 | "production": [
25 | ">0.2%",
26 | "not dead",
27 | "not op_mini all"
28 | ],
29 | "development": [
30 | "last 1 chrome version",
31 | "last 1 firefox version",
32 | "last 1 safari version"
33 | ]
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/react-router/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dmCas/React-study/19cc2c81b77f0850c1e029050b260447c849624d/react-router/public/favicon.ico
--------------------------------------------------------------------------------
/react-router/public/logo192.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dmCas/React-study/19cc2c81b77f0850c1e029050b260447c849624d/react-router/public/logo192.png
--------------------------------------------------------------------------------
/react-router/public/logo512.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dmCas/React-study/19cc2c81b77f0850c1e029050b260447c849624d/react-router/public/logo512.png
--------------------------------------------------------------------------------
/react-router/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 | "src": "logo192.png",
12 | "type": "image/png",
13 | "sizes": "192x192"
14 | },
15 | {
16 | "src": "logo512.png",
17 | "type": "image/png",
18 | "sizes": "512x512"
19 | }
20 | ],
21 | "start_url": ".",
22 | "display": "standalone",
23 | "theme_color": "#000000",
24 | "background_color": "#ffffff"
25 | }
26 |
--------------------------------------------------------------------------------
/react-router/public/robots.txt:
--------------------------------------------------------------------------------
1 | # https://www.robotstxt.org/robotstxt.html
2 | User-agent: *
3 | Disallow:
4 |
--------------------------------------------------------------------------------
/react-router/src/App.css:
--------------------------------------------------------------------------------
1 | .App {
2 | text-align: center;
3 | }
4 |
5 | .App-logo {
6 | height: 40vmin;
7 | pointer-events: none;
8 | }
9 |
10 | @media (prefers-reduced-motion: no-preference) {
11 | .App-logo {
12 | animation: App-logo-spin infinite 20s linear;
13 | }
14 | }
15 |
16 | .App-header {
17 | background-color: #282c34;
18 | min-height: 100vh;
19 | display: flex;
20 | flex-direction: column;
21 | align-items: center;
22 | justify-content: center;
23 | font-size: calc(10px + 2vmin);
24 | color: white;
25 | }
26 |
27 | .App-link {
28 | color: #61dafb;
29 | }
30 |
31 | @keyframes App-logo-spin {
32 | from {
33 | transform: rotate(0deg);
34 | }
35 | to {
36 | transform: rotate(360deg);
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/react-router/src/App.test.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { render } from '@testing-library/react';
3 | import App from './App';
4 |
5 | test('renders learn react link', () => {
6 | const { getByText } = render();
7 | const linkElement = getByText(/learn react/i);
8 | expect(linkElement).toBeInTheDocument();
9 | });
10 |
--------------------------------------------------------------------------------
/react-router/src/index.css:
--------------------------------------------------------------------------------
1 | body {
2 | margin: 0;
3 | font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen',
4 | 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue',
5 | sans-serif;
6 | -webkit-font-smoothing: antialiased;
7 | -moz-osx-font-smoothing: grayscale;
8 | }
9 |
10 | code {
11 | font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New',
12 | monospace;
13 | }
14 |
--------------------------------------------------------------------------------
/react-router/src/index.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import ReactDOM from 'react-dom';
3 | import './index.css';
4 | import App from './App';
5 | import * as serviceWorker from './serviceWorker';
6 |
7 | ReactDOM.render(, document.getElementById('root'));
8 |
9 | // If you want your app to work offline and load faster, you can change
10 | // unregister() to register() below. Note this comes with some pitfalls.
11 | // Learn more about service workers: https://bit.ly/CRA-PWA
12 | serviceWorker.unregister();
13 |
--------------------------------------------------------------------------------
/react-router/src/setupTests.js:
--------------------------------------------------------------------------------
1 | // jest-dom adds custom jest matchers for asserting on DOM nodes.
2 | // allows you to do things like:
3 | // expect(element).toHaveTextContent(/react/i)
4 | // learn more: https://github.com/testing-library/jest-dom
5 | import '@testing-library/jest-dom/extend-expect';
6 |
--------------------------------------------------------------------------------
/readme.md:
--------------------------------------------------------------------------------
1 | ## React学习
--------------------------------------------------------------------------------
/weather/.gitignore:
--------------------------------------------------------------------------------
1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
2 |
3 | # dependencies
4 | /node_modules
5 | /.pnp
6 | .pnp.js
7 |
8 | # testing
9 | /coverage
10 |
11 | # production
12 | /build
13 |
14 | # misc
15 | .DS_Store
16 | .env.local
17 | .env.development.local
18 | .env.test.local
19 | .env.production.local
20 |
21 | npm-debug.log*
22 | yarn-debug.log*
23 | yarn-error.log*
24 |
--------------------------------------------------------------------------------
/weather/config/jest/cssTransform.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | // This is a custom Jest transformer turning style imports into empty objects.
4 | // http://facebook.github.io/jest/docs/en/webpack.html
5 |
6 | module.exports = {
7 | process() {
8 | return 'module.exports = {};';
9 | },
10 | getCacheKey() {
11 | // The output is always the same.
12 | return 'cssTransform';
13 | },
14 | };
15 |
--------------------------------------------------------------------------------
/weather/config/jest/fileTransform.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | const path = require('path');
4 | const camelcase = require('camelcase');
5 |
6 | // This is a custom Jest transformer turning file imports into filenames.
7 | // http://facebook.github.io/jest/docs/en/webpack.html
8 |
9 | module.exports = {
10 | process(src, filename) {
11 | const assetFilename = JSON.stringify(path.basename(filename));
12 |
13 | if (filename.match(/\.svg$/)) {
14 | // Based on how SVGR generates a component name:
15 | // https://github.com/smooth-code/svgr/blob/01b194cf967347d43d4cbe6b434404731b87cf27/packages/core/src/state.js#L6
16 | const pascalCaseFilename = camelcase(path.parse(filename).name, {
17 | pascalCase: true,
18 | });
19 | const componentName = `Svg${pascalCaseFilename}`;
20 | return `const React = require('react');
21 | module.exports = {
22 | __esModule: true,
23 | default: ${assetFilename},
24 | ReactComponent: React.forwardRef(function ${componentName}(props, ref) {
25 | return {
26 | $$typeof: Symbol.for('react.element'),
27 | type: 'svg',
28 | ref: ref,
29 | key: null,
30 | props: Object.assign({}, props, {
31 | children: ${assetFilename}
32 | })
33 | };
34 | }),
35 | };`;
36 | }
37 |
38 | return `module.exports = ${assetFilename};`;
39 | },
40 | };
41 |
--------------------------------------------------------------------------------
/weather/config/pnpTs.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | const { resolveModuleName } = require('ts-pnp');
4 |
5 | exports.resolveModuleName = (
6 | typescript,
7 | moduleName,
8 | containingFile,
9 | compilerOptions,
10 | resolutionHost
11 | ) => {
12 | return resolveModuleName(
13 | moduleName,
14 | containingFile,
15 | compilerOptions,
16 | resolutionHost,
17 | typescript.resolveModuleName
18 | );
19 | };
20 |
21 | exports.resolveTypeReferenceDirective = (
22 | typescript,
23 | moduleName,
24 | containingFile,
25 | compilerOptions,
26 | resolutionHost
27 | ) => {
28 | return resolveModuleName(
29 | moduleName,
30 | containingFile,
31 | compilerOptions,
32 | resolutionHost,
33 | typescript.resolveTypeReferenceDirective
34 | );
35 | };
36 |
--------------------------------------------------------------------------------
/weather/public/city/hotcity.json:
--------------------------------------------------------------------------------
1 | {
2 | "success": true,
3 | "aaa": 2,
4 | "hotList":["北京", "广州", "深圳", "上海", "南京", "杭州", "武汉"]
5 | }
--------------------------------------------------------------------------------
/weather/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dmCas/React-study/19cc2c81b77f0850c1e029050b260447c849624d/weather/public/favicon.ico
--------------------------------------------------------------------------------
/weather/public/logo192.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dmCas/React-study/19cc2c81b77f0850c1e029050b260447c849624d/weather/public/logo192.png
--------------------------------------------------------------------------------
/weather/public/logo512.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dmCas/React-study/19cc2c81b77f0850c1e029050b260447c849624d/weather/public/logo512.png
--------------------------------------------------------------------------------
/weather/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 | "src": "logo192.png",
12 | "type": "image/png",
13 | "sizes": "192x192"
14 | },
15 | {
16 | "src": "logo512.png",
17 | "type": "image/png",
18 | "sizes": "512x512"
19 | }
20 | ],
21 | "start_url": ".",
22 | "display": "standalone",
23 | "theme_color": "#000000",
24 | "background_color": "#ffffff"
25 | }
26 |
--------------------------------------------------------------------------------
/weather/public/robots.txt:
--------------------------------------------------------------------------------
1 | # https://www.robotstxt.org/robotstxt.html
2 | User-agent: *
3 | Disallow:
4 |
--------------------------------------------------------------------------------
/weather/scripts/test.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | // Do this as the first thing so that any code reading it knows the right env.
4 | process.env.BABEL_ENV = 'test';
5 | process.env.NODE_ENV = 'test';
6 | process.env.PUBLIC_URL = '';
7 |
8 | // Makes the script crash on unhandled rejections instead of silently
9 | // ignoring them. In the future, promise rejections that are not handled will
10 | // terminate the Node.js process with a non-zero exit code.
11 | process.on('unhandledRejection', err => {
12 | throw err;
13 | });
14 |
15 | // Ensure environment variables are read.
16 | require('../config/env');
17 |
18 |
19 | const jest = require('jest');
20 | const execSync = require('child_process').execSync;
21 | let argv = process.argv.slice(2);
22 |
23 | function isInGitRepository() {
24 | try {
25 | execSync('git rev-parse --is-inside-work-tree', { stdio: 'ignore' });
26 | return true;
27 | } catch (e) {
28 | return false;
29 | }
30 | }
31 |
32 | function isInMercurialRepository() {
33 | try {
34 | execSync('hg --cwd . root', { stdio: 'ignore' });
35 | return true;
36 | } catch (e) {
37 | return false;
38 | }
39 | }
40 |
41 | // Watch unless on CI or explicitly running all tests
42 | if (
43 | !process.env.CI &&
44 | argv.indexOf('--watchAll') === -1 &&
45 | argv.indexOf('--watchAll=false') === -1
46 | ) {
47 | // https://github.com/facebook/create-react-app/issues/5210
48 | const hasSourceControl = isInGitRepository() || isInMercurialRepository();
49 | argv.push(hasSourceControl ? '--watch' : '--watchAll');
50 | }
51 |
52 |
53 | jest.run(argv);
54 |
--------------------------------------------------------------------------------
/weather/src/App.css:
--------------------------------------------------------------------------------
1 | .App {
2 | text-align: center;
3 | }
4 |
5 | .App-logo {
6 | height: 40vmin;
7 | pointer-events: none;
8 | }
9 |
10 | @media (prefers-reduced-motion: no-preference) {
11 | .App-logo {
12 | animation: App-logo-spin infinite 20s linear;
13 | }
14 | }
15 |
16 | .App-header {
17 | background-color: #282c34;
18 | min-height: 100vh;
19 | display: flex;
20 | flex-direction: column;
21 | align-items: center;
22 | justify-content: center;
23 | font-size: calc(10px + 2vmin);
24 | color: white;
25 | }
26 |
27 | .App-link {
28 | color: #61dafb;
29 | }
30 |
31 | @keyframes App-logo-spin {
32 | from {
33 | transform: rotate(0deg);
34 | }
35 | to {
36 | transform: rotate(360deg);
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/weather/src/App.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { BrowserRouter as Router , Route} from 'react-router-dom'
3 | import './App.css';
4 | import 'antd/dist/antd.css'
5 | import MainPage from './pages/main'
6 | import SearchCity from './pages/search'
7 | import { Provider } from 'react-redux'
8 | import store from './store'
9 | import Test from './pages/test';
10 |
11 | function App() {
12 | return (
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 | );
22 | }
23 |
24 | export default App;
25 |
--------------------------------------------------------------------------------
/weather/src/App.test.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { render } from '@testing-library/react';
3 | import App from './App';
4 |
5 | test('renders learn react link', () => {
6 | const { getByText } = render();
7 | const linkElement = getByText(/learn react/i);
8 | expect(linkElement).toBeInTheDocument();
9 | });
10 |
--------------------------------------------------------------------------------
/weather/src/index.css:
--------------------------------------------------------------------------------
1 | body {
2 | margin: 0;
3 | font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen',
4 | 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue',
5 | sans-serif;
6 | -webkit-font-smoothing: antialiased;
7 | -moz-osx-font-smoothing: grayscale;
8 | }
9 |
10 | code {
11 | font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New',
12 | monospace;
13 | }
14 |
--------------------------------------------------------------------------------
/weather/src/index.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import ReactDOM from 'react-dom';
3 | import './index.css';
4 | import App from './App';
5 | import * as serviceWorker from './serviceWorker';
6 |
7 | ReactDOM.render(, document.getElementById('root'));
8 |
9 | // If you want your app to work offline and load faster, you can change
10 | // unregister() to register() below. Note this comes with some pitfalls.
11 | // Learn more about service workers: https://bit.ly/CRA-PWA
12 | serviceWorker.unregister();
13 |
--------------------------------------------------------------------------------
/weather/src/pages/main/component/cloudy.js:
--------------------------------------------------------------------------------
1 | import React from 'react'
2 | import { Cloudy, Sunny } from './style'
3 |
4 | class WeatherCircle extends React.Component {
5 | render() {
6 | return (
7 |
8 |
9 |
10 | //
11 | //
12 | //
13 |
14 | )
15 | }
16 | }
17 |
18 | export default WeatherCircle
--------------------------------------------------------------------------------
/weather/src/pages/main/component/style.js:
--------------------------------------------------------------------------------
1 | import styled from 'styled-components'
2 |
3 | export const Cloudy = styled.div`
4 | position: absolute;
5 | right: 30px;
6 | top: 30px;
7 | width: 80px;
8 | height: 80px;
9 | border-radius: 100%;
10 | background: linear-gradient(to top right,#000000 0,#eee 90%);
11 | box-shadow: 0 0 0 0.1px #280000, 0 0 10px -1px #C0C0C0;
12 | .cloud {
13 | position: absolute;
14 | top: 25%;
15 | left: 40%;
16 | width: 20px;
17 | height: 6px;
18 | border-radius: 4px;
19 | background-color: #eee;
20 | box-shadow: 0 0 4px 2px #e6e8db,0 0 20px -2px #c9e8de;
21 | animation: move 4000ms infinite ease-in-out;
22 | }
23 | @keyframes move {
24 | 50% {
25 | transform: translateX(-10px);
26 | }
27 | }
28 | .cloud::before {
29 | left: 3px;
30 | height: 10px;
31 | width: 10px;
32 | }
33 | .cloud::after {
34 | left: 9px;
35 | height: 7px;
36 | width: 7px;
37 | }
38 | .cloud::before, .cloud::after {
39 | content: '';
40 | position: inherit;
41 | border-radius: 100%;
42 | background-color: inherit;
43 | box-shadow: inherit;
44 | bottom: 40%;
45 | }
46 | `
47 |
48 | export const Sunny = styled.div`
49 | position: absolute;
50 | right: 30px;
51 | top: 30px;
52 | width: 80px;
53 | height: 80px;
54 | border-radius: 100%;
55 | background: linear-gradient(to top right, #fc5830 0%, #f98c24 65%);
56 | box-shadow: 0 0 0 1px #e6e8db,0 0 10px -1px #c9e8de;
57 | .sun{
58 | position: absolute;
59 | top: 20%;
60 | left: 80%;
61 | transform: translate(-50%, -50%);
62 | width: 40%;
63 | height: 40%;
64 | border-radius: 100%;
65 | background: #ffeb3b;
66 | box-shadow: 0 0 0 0.02em #e6e8db, 0 0 0.3em -0.03em #fd6f21;
67 | }
68 | `
69 |
70 |
--------------------------------------------------------------------------------
/weather/src/pages/main/loadable.js:
--------------------------------------------------------------------------------
1 | import Loadable from 'react-loadable';
2 |
3 | const LoadableComponent = Loadable({
4 | loader: () => import('./index'),
5 | loading() {
6 | return 正在加载...
7 | }
8 | });
9 |
10 | export default () =>
--------------------------------------------------------------------------------
/weather/src/pages/search/loadable.js:
--------------------------------------------------------------------------------
1 | import Loadable from 'react-loadable';
2 |
3 | const LoadableComponent = Loadable({
4 | loader: () => import('./index'),
5 | loading() {
6 | return 正在加载...
7 | }
8 | });
9 |
10 | export default () =>
--------------------------------------------------------------------------------
/weather/src/pages/search/style.js:
--------------------------------------------------------------------------------
1 | import styled from 'styled-components'
2 |
3 | export const SearchWrapper = styled.div`
4 | margin: 0;
5 | padding: 10px 10px 0 10px;
6 | button{
7 | right: 10px;
8 | position: absolute;
9 | }
10 | a{
11 | color: #000;
12 | }
13 | `
14 |
15 | export const Recommend = styled.div`
16 | padding-top: 25px;
17 | box-sizing: border-box;
18 | p{
19 | font-weight: bold;
20 | padding-left: 3px;
21 | }
22 | `
23 |
24 | export const TagWrapper = styled.div`
25 | width: 112px;
26 | height: 25px;
27 | text-align: center;
28 | line-height: 25px;
29 | background: #eee;
30 | font-size: 12px;
31 | margin: 4px 6px 2px 0;
32 | `
33 | export const Tag = styled.div`
34 | display: flex;
35 | flex-wrap: wrap;
36 | justify-content: space-between;
37 | box-sizing: border-box;
38 | `
39 | export const His = styled.div`
40 | display: flex;
41 | flex-wrap: wrap;
42 | /* justify-content: space-between; */
43 | justify-content: flex-start;
44 | box-sizing: border-box;
45 | `
46 |
--------------------------------------------------------------------------------
/weather/src/pages/test/index.js:
--------------------------------------------------------------------------------
1 | import { Select } from 'antd';
2 | import React from 'react'
3 | import axios from 'axios'
4 | const { Option } = Select;
5 | let timeout;
6 | let currentValue;
7 |
8 | function fetch(value, callback) {
9 | if (timeout) {
10 | clearTimeout(timeout);
11 | timeout = null;
12 | }
13 | currentValue = value;
14 |
15 | function fake() {
16 | axios.get('/city/citys.json').then((res) => {
17 | var tem = []
18 | tem = res.data.citys.filter((item) => item.citysName.includes(value))
19 | // this.setState({
20 | // showsearch: this.tem[0].citys.slice(0,15)
21 | // })
22 | console.log(tem.slice(0,10))
23 | callback(tem.slice(0,10))
24 | })
25 | }
26 |
27 | timeout = setTimeout(fake, 300);
28 | }
29 |
30 | class SearchInput extends React.Component {
31 | state = {
32 | data: [],
33 | value: undefined,
34 | };
35 |
36 | handleSearch = value => {
37 | if (value) {
38 | fetch(value, data => this.setState({ data }));
39 | } else {
40 | this.setState({ data: [] });
41 | }
42 | };
43 |
44 | handleChange = value => {
45 | this.setState({ value });
46 | };
47 |
48 | render() {
49 | console.log(this.state.data)
50 | const options = this.state.data.map(d => );
51 | return (
52 |
66 | );
67 | }
68 | }
69 |
70 | export default SearchInput
--------------------------------------------------------------------------------
/weather/src/setupTests.js:
--------------------------------------------------------------------------------
1 | // jest-dom adds custom jest matchers for asserting on DOM nodes.
2 | // allows you to do things like:
3 | // expect(element).toHaveTextContent(/react/i)
4 | // learn more: https://github.com/testing-library/jest-dom
5 | import '@testing-library/jest-dom/extend-expect';
6 |
--------------------------------------------------------------------------------
/weather/src/static/iconfont/iconfont.eot:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dmCas/React-study/19cc2c81b77f0850c1e029050b260447c849624d/weather/src/static/iconfont/iconfont.eot
--------------------------------------------------------------------------------
/weather/src/static/iconfont/iconfont.json:
--------------------------------------------------------------------------------
1 | {
2 | "id": "1714637",
3 | "name": "weather",
4 | "font_family": "iconfont",
5 | "css_prefix_text": "icon-",
6 | "description": "",
7 | "glyphs": [
8 | {
9 | "icon_id": "10836545",
10 | "name": "叶子",
11 | "font_class": "yezi",
12 | "unicode": "e663",
13 | "unicode_decimal": 58979
14 | },
15 | {
16 | "icon_id": "12924200",
17 | "name": "口罩",
18 | "font_class": "kouzhao",
19 | "unicode": "e640",
20 | "unicode_decimal": 58944
21 | }
22 | ]
23 | }
24 |
--------------------------------------------------------------------------------
/weather/src/static/iconfont/iconfont.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dmCas/React-study/19cc2c81b77f0850c1e029050b260447c849624d/weather/src/static/iconfont/iconfont.ttf
--------------------------------------------------------------------------------
/weather/src/static/iconfont/iconfont.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dmCas/React-study/19cc2c81b77f0850c1e029050b260447c849624d/weather/src/static/iconfont/iconfont.woff
--------------------------------------------------------------------------------
/weather/src/static/iconfont/iconfont.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dmCas/React-study/19cc2c81b77f0850c1e029050b260447c849624d/weather/src/static/iconfont/iconfont.woff2
--------------------------------------------------------------------------------
/weather/src/static/img/1.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dmCas/React-study/19cc2c81b77f0850c1e029050b260447c849624d/weather/src/static/img/1.jpg
--------------------------------------------------------------------------------
/weather/src/static/img/2.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dmCas/React-study/19cc2c81b77f0850c1e029050b260447c849624d/weather/src/static/img/2.jpg
--------------------------------------------------------------------------------
/weather/src/static/img/3.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dmCas/React-study/19cc2c81b77f0850c1e029050b260447c849624d/weather/src/static/img/3.jpg
--------------------------------------------------------------------------------
/weather/src/static/img/4.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dmCas/React-study/19cc2c81b77f0850c1e029050b260447c849624d/weather/src/static/img/4.jpg
--------------------------------------------------------------------------------
/weather/src/static/img/5.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dmCas/React-study/19cc2c81b77f0850c1e029050b260447c849624d/weather/src/static/img/5.jpg
--------------------------------------------------------------------------------
/weather/src/static/img/中雨.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dmCas/React-study/19cc2c81b77f0850c1e029050b260447c849624d/weather/src/static/img/中雨.png
--------------------------------------------------------------------------------
/weather/src/static/img/多云.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dmCas/React-study/19cc2c81b77f0850c1e029050b260447c849624d/weather/src/static/img/多云.png
--------------------------------------------------------------------------------
/weather/src/static/img/大雨.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dmCas/React-study/19cc2c81b77f0850c1e029050b260447c849624d/weather/src/static/img/大雨.png
--------------------------------------------------------------------------------
/weather/src/static/img/小雨.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dmCas/React-study/19cc2c81b77f0850c1e029050b260447c849624d/weather/src/static/img/小雨.png
--------------------------------------------------------------------------------
/weather/src/static/img/晴.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dmCas/React-study/19cc2c81b77f0850c1e029050b260447c849624d/weather/src/static/img/晴.png
--------------------------------------------------------------------------------
/weather/src/static/img/阴.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dmCas/React-study/19cc2c81b77f0850c1e029050b260447c849624d/weather/src/static/img/阴.png
--------------------------------------------------------------------------------
/weather/src/static/img/阵雨.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dmCas/React-study/19cc2c81b77f0850c1e029050b260447c849624d/weather/src/static/img/阵雨.png
--------------------------------------------------------------------------------
/weather/src/static/img/雷阵雨.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dmCas/React-study/19cc2c81b77f0850c1e029050b260447c849624d/weather/src/static/img/雷阵雨.png
--------------------------------------------------------------------------------
/weather/src/store/actionCreators.js:
--------------------------------------------------------------------------------
1 | // import axios from 'axios'
2 | import * as actionTypes from './actionTypes'
3 |
4 | const cityApi = (city) => ({
5 | type: actionTypes.CURRENT_CITY,
6 | city
7 | })
8 |
9 | const weatherApi = (data) => ({
10 | type: actionTypes.CURRENT_WEATHER,
11 | weatherData: data
12 | })
13 |
14 | const forecastApi = (data) => ({
15 | type: actionTypes.FORECAST_WEATHER,
16 | forecast: data
17 | })
18 |
19 | export const getCity = (city) => {
20 | return (dispatch) => {
21 | const action = cityApi(city)
22 | dispatch(action)
23 | }
24 | }
25 |
26 | export const getWeather = (data) => {
27 | return (dispatch) => {
28 | const action = weatherApi(data)
29 | dispatch(action)
30 | }
31 | }
32 |
33 | export const getForecast = (data) => {
34 | return (dispatch) => {
35 | const action = forecastApi(data)
36 | dispatch(action)
37 | }
38 | }
39 |
40 | export const getInit = () => {
41 | return (dispatch) => {
42 | const action = {
43 | type : actionTypes.FIRST_INIT,
44 | init: false
45 | }
46 | dispatch(action)
47 | }
48 | }
49 |
50 | export const changeCity = (city) => {
51 | return dispatch => {
52 | const action = {
53 | type : actionTypes.CHANGE_CITY,
54 | city: city
55 | }
56 | dispatch(action)
57 | }
58 | }
--------------------------------------------------------------------------------
/weather/src/store/actionTypes.js:
--------------------------------------------------------------------------------
1 | export const CURRENT_CITY = 'home/CURRENT_CITY'
2 | export const CURRENT_WEATHER = 'home/CURRENT_WEATHER'
3 | export const FORECAST_WEATHER = 'home/ORECAST_WEATHER'
4 |
5 | export const FIRST_INIT = 'home/FIRST_INIT'
6 | export const CHANGE_CITY = 'search/FIRST_INIT'
--------------------------------------------------------------------------------
/weather/src/store/index.js:
--------------------------------------------------------------------------------
1 | import { createStore, compose, applyMiddleware } from 'redux'
2 | import reducer from './reducer'
3 | import thunk from 'redux-thunk'
4 |
5 | const componentEnhanders = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose;
6 |
7 | const enhancer = componentEnhanders(
8 | applyMiddleware(thunk)
9 | )
10 | const store = createStore(reducer, enhancer)
11 |
12 | export default store
--------------------------------------------------------------------------------
/weather/src/store/reducer.js:
--------------------------------------------------------------------------------
1 | import { fromJS } from 'immutable'
2 | import * as actionTypes from './actionTypes'
3 |
4 | const defaultState = fromJS({
5 | city: '',
6 | cityHistory: [],
7 | weatherData: {},
8 | forecast: [],
9 | init: true
10 | })
11 |
12 | export default (state = defaultState, action) => {
13 | if (action.type === actionTypes.CURRENT_CITY) {
14 | return state.set('city', action.city)
15 | }
16 | if (action.type === actionTypes.CURRENT_WEATHER) {
17 | return state.set('weatherData', action.weatherData)
18 | }
19 | if (action.type === actionTypes.FORECAST_WEATHER) {
20 | console.log(action.forecast)
21 | return state.set('forecast', action.forecast)
22 | }
23 | if (action.type === actionTypes.FIRST_INIT) {
24 | return state.set('init', false)
25 | }
26 | if (action.type === actionTypes.CHANGE_CITY) {
27 | return state.merge({
28 | city: action.city,
29 | cityHistory:[...new Set(state.get('cityHistory').concat(action.city))]
30 | }
31 | )
32 | }
33 | return state
34 | }
--------------------------------------------------------------------------------