前端之React学习(三)

前端之React学习(三)

React 脚手架

create-react-app 是 Facebook 官方退出的 react 脚手架

安装(有 node)

  1. npm i -g create-reate-app //全局安装
  2. create-reate-app --v //查看版本

创建项目

  1. cd 需要创建的文件夹中
  2. create-react-app 项目名字

启动项目

npm start

文件解释

  1. public 静态资源文件夹
  2. src 写代码的地方

创建组件

  1. 组件名.js 或者 组件名.jsx
  2. rcc //快捷键
import React, { Component } from "react";

class Home extends Component {
  render() {
    return <div>我是一个组件</div>;
  }
}

export default Home;

引用组件

  1. import 组件名 from “文件路径”
  2. <组件名/>
import Home from "./components/Home";
function App() {
  return (
    <div className="App">
      <Home />
    </div>
  );
}

export default App;

多行标签

  1. 用一个父标签 div 包裹
import React, { Component } from "react";

class Home extends Component {
  render() {
    return (
      <div>
        <div>我是一个组件</div>
        <div>我是一个组件1</div>
      </div>
    );
  }
}

export default Home;
  1. 用一个空标签包裹
import React, { Component } from "react";

class Home extends Component {
  render() {
    return (
      <>
        <div>我是一个组件</div>
        <div>我是一个组件1</div>
      </>
    );
  }
}

export default Home;
  1. 引用 Fragment 标签
import React, { Component ,Fragment} from "react";

class Home extends Component {
  render() {
    return (
      <Fragment>
        <div>我是一个组件</div>
        <div>我是一个组件1</div>
      </Fragment>
    );
  }
}

export default Home;


图片引用

  1. 法一
  • 图片放在 public 中
  1. 法二
  • 图片放在 src 下
  • import 名字 from “图片路径”
  1. 法三
  • 图片放在 src 下
  • <img src={require(“路径”)} />

组件的 props 和 state

  • 父组件
import React, { Component, Fragment } from "react";

import News from "./News";
class Home extends Component {
  render() {
    return (
      <Fragment>
        <div>我是一个父组件</div>
        <div>你好</div>
        <News text="props数据" />
      </Fragment>
    );
  }
}

export default Home;
  • 子组件
import React, { Component } from "react";

class News extends Component {
  constructor(props) {
    super(props);
    this.state = {
      num: 123,
    };
  }
  fun() {
    this.setState({
      num: 165465,
    });
  }
  render() {
    return (
      <div>
        我是子组件-----{this.props.text}------{this.state.num}
        <button onClick={this.fun.bind(this)}>点我修改,state数据</button>
      </div>
    );
  }
}

export default News;

组件的传值

正向传值——父传子(props)

逆向传值——子传父

  1. 子组件中声明数据
  2. 绑定传递父函数
  3. 接收父函数,并编写父函数,函数形参即为接收的子组件的数据
  • 子组件
import React, { Component } from "react";

class News extends Component {
  constructor(props) {
    super(props);
    this.state = {
      zitext: "我是子组件中的数据",
    };
  }

  render() {
    return (
      <div>
        我是子组件
        <div>
          <button onClick={this.props.fufun.bind(this, this.state.zitext)}>
            点我进行子传父
          </button>
        </div>
      </div>
    );
  }
}

export default News;
+ 父组件

import React, { Component, Fragment } from “react”;

import News from “./News”;
class Home extends Component {
constructor(props) {
super(props);
this.state = {
text: “我是默认值”,
};
}
datafun = (text) => {
this.setState({
text, //ES6 中,text 和 text:text 相同
});
console.log(text);
};
render() {
return (

我是一个父组件
你好
{this.state.text}
); } }

export default Home;


第三种——同级传值(pubsub.js)

  • Com1 的数据传给 Com2
  1. 下载
    npm i --save pubsub-js
  2. 设置同级组件 Com1,Com2
  3. 在 Com1 中,引用
import Pubsub from "pubsub-js"

定义绑击事件函数名,定义此函数

Pubsub.publish.("事件名","传递的数据")
  1. 在 Com2 中
    引用
import Pubsub from "pubsub-js"

在 constructor 中调用

Pubsub.subscribe("事件名",(msg,接收数据)=>{})
  • 例子 News 传值给 Phone
  • News
import React, { Component } from "react";

import Pubsub from "pubsub-js";
class News extends Component {
  constructor(props) {
    super(props);
    this.state = {
      num: 123,
      zitext: "我是子组件中的数据",
    };
  }
  pubsub() {
    Pubsub.publish("evt", this.state.num);
  }
  render() {
    return (
      <div>
        我是子组件News
        <div>
          <button onClick={this.props.fufun.bind(this, this.state.zitext)}>
            点我进行子传父
          </button>
        </div>
        <button onClick={this.pubsub.bind(this)}>点我同级传值</button>
      </div>
    );
  }
}

export default News;
  • Phone
import React, { Component } from "react";

import Pubsub from "pubsub-js";
class Phone extends Component {
  constructor(props) {
    super(props);
    Pubsub.subscribe("evt", (msg, data) => {
      console.log(data);
    });
  }
  render() {
    return <div>我是子组件Phone</div>;
  }
}

export default Phone;

axios(数据请求)& json-server(数据模拟)

下载

  • axios(数据请求)
    npm i --save axios
  • json-server(数据模拟)
    npm i json-server -g

数据模拟的启动

  1. cd mock 文件夹下
  2. json-server (json 数据的文件名字) --port 4000

数据请求

  1. 组件中引用 axios
    import axios from 'axios'
  2. 组件中请求数据
componentDidMount(){
  this.ajaxfun()
}
ajaxfun=()=>{
  axios.get("http://localhost:4000/arr").then((ok)=>{
    console.log(ok)
  })
}
  1. 调用组件
import 组件名 from "组件路径"
<组件名/>
  • 例子
  • mock 下的 data.json 文件
{
  "arr":[
    {"id":1,"name":"小米1"},
    {"id":2,"name":"小米2"},
    {"id":3,"name":"小米3"},
    {"id":4,"name":"小米4"}
  ]
}
  • 组件
import React, { Component } from "react";

import axios from "axios";
class Home extends Component {
  // 自动调用函数
  componentDidMount() {
    this.ajaxfun();
  }
  //函数axios请求数据
  ajaxfun = () => {
    axios.get("http://localhost:4000/arr").then((ok) => {
      console.log(ok);
      this.setState({
        arr: ok.data,
      });
    });
  };
  //接收数据
  constructor(props) {
    super(props);
    this.state = {
      arr: [],
    };
  }
  render() {
    return (
      <div>
        {/*渲染数据 */}
        {this.state.arr.map((v, i) => {
          return <p key={i}>{v.name}</p>;
        })}
      </div>
    );
  }
}

export default Home;

react 处理跨域问题

正向代理——开发环境

解释:
一个位于客户端和目标服务器之间的代理服务器
为了湖区目标服务器的内容,客户端向代理服务器发送一个请求
代理服务器帮助我们去目标服务器获取数据并且返回给我们

反向代理——上线环境

解释
可以通过代理服务器来接收网络上的请求连接,
然后这个请求转发给内部的网络服务器上,并且把这个服务器上得到的数据返回给请求的客户端
这个时候代理服务器对外的表现就是一个反向代理
(后端人员配置服务器)

例子–模拟请求真实的网络接口

  • 中国天气网中的数据
  1. 找到文件
    项目\node_modules\react-scripts\config\webpackDevServer.config.js
  2. 修改
   proxy:{
      "api":{
        target:"http://www.weather.com.cn/data/cityinfo",//只用改target地址
        changeOrigin:true,
        "pathRewrite":{
          "^api":"/"
        }
      }
    },

路由

解释:
根据 url 的不同来切换对应的组件
实现 spa(单页面应用)在页面切换的时候不会刷新,更加接近原生的效果

基本知识

  • react-router 只提供了一些核心的 api
  • react-router-dom 更加全面
  • 路由模式
    • hash HashRouter
      hash 模式,带 # 号,刷新时页面不会丢失
    • browser BrowserRouter
      历史记录模式,没有 # 号,他是通过历史记录 api 来进行路由切换,刷新会丢失,本地模式不会

下载

npm i --save react-router-dom

index.js 引用

import {BrowserRouter} from "react-router-dom

index.js 中 BrowserRouter 标签包裹

ReactDOM.render(
  <BrowserRouter>
    <App />
  </BrowserRouter>,
  document.getElementById("root")
);

配置路由

  • 根组件中引用路由
    import { Route } from "react-router-dom";
  • 根组件中引用多个组件
import Home from "./components/Home";
import Phone from "./components/Phone";
import User from "./components/User";
  • 根组件渲染组件
 <Route path="/home" component={Home} />
      <Route path="/phone" component={Phone} />
      <Route path="/user" component={User} />

hash 模式注意:

  1. 直接在引用时修改
    import {HashRouter} from "react-router-dom
  2. 包裹时修改
  3. 其余不变
  4. 路径有#

路由导航

Link,NavLink

  • 引用
  • 标签
    to=“去哪里”
    注意:
    Navlink—可以动态给选中的标签添加 active 的类名

exact 属性

精准匹配

switch 唯一渲染

  • 引用
  • 标签

Redirect 重定向

  • 引用
  • 标签
    <Redirect from="/" to="/home" exact component={Home} />

二级路由

  • home
import React, { Component } from "react";

import axios from "axios";
import { Route, NavLink } from "react-router-dom";
import homea from "./home/homea";
import homeb from "./home/homeb";
class Home extends Component {
  conmponetDidMount() {
    axios.get("/api/101320101.html").then((ok) => {
      console.log(ok);
    });
  }
  render() {
    return (
      <div>
        <div>Home组件</div>
        {/*二级页面 */}
        <div>
          <NavLink to="/home/homea">to homea</NavLink>
          <NavLink to="/home/homeb">to homeb</NavLink>
        </div>
        <div>
          <Route path="/home/homea" component={homea} />
          <Route path="/home/homeb" component={homeb} />
        </div>
      </div>
    );
  }
}

export default Home;
  • homea
import React, { Component } from "react";

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

export default homea;
  • homeb
import React, { Component } from "react";

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

export default homeb;

更多文章链接

前端之React学习(一)
前端之React学习(二)
前端之React学习(四)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值