当前位置:   article > 正文

【重点突破】—— create-react-app&React组件化思想

create-react-app 和react 区别

前言:正在学习react大众点评项目课程的todoList应用阶段,学习react、redux、react-router基础知识。


一、 React项目脚手架:create-react-app

  • 新建项目:
    npx create-react-app 项目名
    
    

    注:(npm >= 5.2 )  

  • 三个依赖:react、react-dom、react-scripts
  • 四个命令:start、build、test、eject(将webpack的封装弹射出来)
    1. cd 项目名
    2. npm start (npm run startrun可省略)

二、使用Mock数据 —— 前后端分离模拟通过http获取mock数据的过程

方式一: 代理到mock服务器

需要开启一台mock服务器,将前端请求转发到这台mock服务器上

安装:

npm install -g serve 

启动:

serve

服务器地址:http://localhost:5000  

新建api目录,创建data.json文件

脚手架集成了请求转发的功能:package.json文件中

1.create-react-app脚手架低于2.0版本时候,可以使用对象类型

  1. "proxy": {
  2. "/api": {
  3. "target": "http://localhost:5000",
  4. "changeOrigin": true
  5. }
  6. }  

2.最新的create-react-app脚手架2.0版本以上只能配置string类型

"proxy": "http://localhost:5000" 

3.最好的方式可以通过middleware中间件进行配置(可以配置多个代理)

npm install http-proxy-middleware --save

  1. const proxy = require("http-proxy-middleware");
  2. module.exports = function(app) {
  3. app.use(
  4. proxy("/api/", {
  5. target: "http://localhost:5000",//跨域地址
  6. changeOrigin: true
  7. })
  8. );
  9. };

请求地址:localhost:3000/api/data.json

注意:package.json内容发生了修改,必须重启应用,才能生效。

方式二: 直接将mock数据放到项目public/mock文件夹下(采用)

原因:public文件夹下的内容不会被构建,是静态资源,可直接使用,这样在服务器上,就可以用http方式请求到mock数据了。

三、React思维方式:组件化思想

1.组件划分原则

解耦:降低单一模块/组件的复杂度

复用:保证组件一致性,提升开发效率

组件颗粒度需要避免过大或过小!

2.编写静态组件

开发过程解耦:静态页面和动态交互

组件开发顺序:自上而下 or 自下而上

App -> TodoList -> Todo -> AddTodo -> Footer

3.什么是state

代表UI的完整且最小状态集合

4.如何判断

是否通过父组件props传入?

是否不会随着时间、交互操作变化?

是否可以通过其它state或props计算得到?

5.State的双层含义

代表应用UI的所有状态的集合

代表集合中的每一部分(待办事项列表、新增输入框文本、筛选条件)

6.分析State保存位置

确定依赖state的每一个组件

如果某个state被多个组件依赖,寻找共同的父组件(状态上移)

7.添加交互行为

借助props,添加反向数据流

新增todo、修改todo状态、过滤显示

8.代码

src->index.js

  1. import React from 'react';
  2. import ReactDOM from 'react-dom';
  3. import App from './components/App';
  4. ReactDOM.render(<App />, document.getElementById('root'));  

src->components->App.js

  1. import React, { Component } from "react";
  2. import AddTodo from "./AddTodo";
  3. import TodoList from "./TodoList";
  4. import Footer from "./Footer";
  5. class App extends Component {
  6. constructor(props) {
  7. super(props);
  8. this.state = {
  9. todos: [],
  10. filter: "all"
  11. };
  12. this.nextTodoId = 0;
  13. }
  14. render() {
  15. const todos = this.getVisibleTodos();
  16. const { filter } = this.state;
  17. return (
  18. <div>
  19. <AddTodo addTodo={this.addTodo} />
  20. <TodoList todos={todos} toggleTodo={this.toggleTodo} />
  21. <Footer
  22. filter={filter}
  23. setVisibilityFilter={this.setVisibilityFilter}
  24. />
  25. </div>
  26. );
  27. }
  28. getVisibleTodos = () => {
  29. const currentFilter = this.state.filter;
  30. return this.state.todos.filter(item => {
  31. if (currentFilter === "active") {
  32. return !item.completed;
  33. } else if (currentFilter === "completed") {
  34. return item.completed;
  35. } else {
  36. return true;
  37. }
  38. });
  39. };
  40. addTodo = text => {
  41. const todo = {
  42. id: this.nextTodoId++,
  43. text,
  44. completed: false
  45. };
  46. const newTodos = [todo, ...this.state.todos];
  47. this.setState({
  48. todos: newTodos
  49. });
  50. };
  51. toggleTodo = id => {
  52. const newTodos = this.state.todos.map(item => {
  53. return item.id === id ? { ...item, completed: !item.completed } : item;
  54. });
  55. this.setState({
  56. todos: newTodos
  57. });
  58. };
  59. setVisibilityFilter = filter => {
  60. this.setState({
  61. filter
  62. });
  63. };
  64. }
  65. export default App;  

src->components->TodoList.js

  1. import React, { Component } from 'react';
  2. import Todo from "./Todo";
  3. class TodoList extends Component {
  4. render() {
  5. const {todos, toggleTodo} = this.props;
  6. return (
  7. <ul>
  8. {
  9. todos.map(todo => {
  10. return <Todo key={todo.id} {...todo}
  11. onClick={() => {toggleTodo(todo.id)}}/>
  12. })
  13. }
  14. </ul>
  15. );
  16. }
  17. }
  18. export default TodoList;  

src->components->Todo.js

  1. import React, { Component } from "react";
  2. class Todo extends Component {
  3. render() {
  4. const { completed, text, onClick } = this.props;
  5. return (
  6. <li
  7. onClick={onClick}
  8. style={{
  9. textDecoration: completed ? "line-through" : "none"
  10. }}
  11. >
  12. {text}
  13. </li>
  14. );
  15. }
  16. }
  17. export default Todo;  

src->components->AddTodo.js

  1. import React, { Component } from 'react';
  2. class AddTodo extends Component {
  3. constructor(props) {
  4. super(props);
  5. this.state = {
  6. text: ''
  7. }
  8. }
  9. render() {
  10. return (
  11. <div>
  12. <input value={this.state.text} onChange={this.handleChange}/>
  13. <button onClick={this.handleClick}>Add</button>
  14. </div>
  15. );
  16. }
  17. handleChange = (e) => {
  18. this.setState({
  19. text: e.target.value
  20. })
  21. }
  22. handleClick = () => {
  23. this.props.addTodo(this.state.text);
  24. }
  25. }
  26. export default AddTodo; 

src->components->Footer.js

  1. import React, { Component } from "react";
  2. class Footer extends Component {
  3. render() {
  4. const { filter, setVisibilityFilter } = this.props;
  5. return (
  6. <div>
  7. <span>Show:</span>
  8. <button
  9. disabled={filter === "all"}
  10. onClick={() => setVisibilityFilter("all")}
  11. >
  12. All
  13. </button>
  14. <button
  15. disabled={filter === "active"}
  16. onClick={() => setVisibilityFilter("active")}
  17. >
  18. Active
  19. </button>
  20. <button
  21. disabled={filter === "completed"}
  22. onClick={() => setVisibilityFilter("completed")}
  23. >
  24. Completed
  25. </button>
  26. </div>
  27. );
  28. }
  29. }
  30. export default Footer;

 注:项目来自慕课网

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/Gausst松鼠会/article/detail/629970
推荐阅读
相关标签
  

闽ICP备14008679号