美文网首页
React的Hello World

React的Hello World

作者: 李霖弢 | 来源:发表于2020-05-11 17:59 被阅读0次
VSCode配置语法高亮

安装Babel JavaScript插件

创建项目

npx create-react-app my-app
cd my-app
npm start
其他还有

npm run build打包项目
npm run eject弹射配置文件
此外在package.json中添加"homepage": ".",可以让打包后的资源路径都变为相对index.html


JSX

JSX并不是单纯的将{}中内容替换后的HTML

  • 属性名均为小驼峰且部分有所变化,如JSX 里的 class 变成了 className,而 tabindex 则变为 tabIndex
  • 自定义属性依然为data-*形式,并可通过dom元素的dataset属性获取
  • {}中的内容默认会进行转义,因此不用担心XSS攻击
  • 没有内容的标签可以使用/> 来闭合。
  • style内容变为对象形式,且key变为小驼峰
  • 图片等资源可以通过以下四种方式引入
    1. import Img from "./images/1.png" <img src={Img} alt=""/>
    2. <img src={require("./images/1.png")} alt=""/>
    3. style={{background:"url("+require("./images/1.png")+")" }}
    4. <img src={process.env.PUBLIC_URL + "/logo512.png"} />;
      其中process.env.PUBLIC_URL等同于index.html中的%PUBLIC_URL%表示public目录,start和build时webpack会将其替换为实际路径

所有JSX其实都是React.createElement() 的语法糖,通过Babel 可以进行转义。

const element = (
  <h1 className="greeting">
    Hello, world!
  </h1>
);

等同于

const element = React.createElement(
  'h1',
  {className: 'greeting'},
  'Hello, world!'
);

渲染

通过render方法将react元素初始化并渲染到页面上

  ReactDOM.render(
    element,
    document.getElementById('root')
  );

其中element可以直接为上文中新建的元素,也可以为元素对应的组件标签,如<MyTest />


组件

接受任意的属性作为入参(即 props),并返回用于描述页面展示内容的 React 元素。

  • 组件必须为大驼峰命名,小写字母开头的组件会被视为原生 DOM 标签。
  • 通常将 App 组件 作为每个新的 React 应用程序的顶层组件。
  • 父元素需传元素给子元素时,可以在子组件标签间写入元素并通过props.children获取,或直接将待传入元素作为属性赋予子元素并通过props获取(类似插槽slot)
函数组件与 class 组件
function Welcome(props) {
  return element;
}

class组件中每次组件更新都会重新触发render

class Welcome extends React.Component {
  render() {
    return element;
  }
}
react元素也可以是自定义组件
const name="Sara";
function Welcome_Fn(props) {
  function speak(e) {
    e.preventDefault();
    alert(this.props.name);
  }
  return <h1 onClick={speak}>Hello, {props.name}</h1>;
}

class Welcome_Class extends React.Component {
  speak() {
    alert(this.props.name);
  }
  render() {
    return <div onClick={onClick=()=>this.speak()}>Hello, {this.props.name}</div>;
  }
}

const element = <Welcome_Class name="Sara" />;
ReactDOM.render(
  //element,
  //<Welcome_Class/>,
  //<Welcome_Fn/>,
  //new Welcome_Class({name}),
  //new Welcome_Fn({name}),
  <div>Hello, {name}</div>,
  document.getElementById('root')
);
props
  • 组件的属性传入为 props
  • 所有 React 组件都必须像纯函数(入参不会被函数内容修改)一样保护它们的 props 不被更改,会发生变化的数据应使用state
state
  • props 类似,但是 state 是私有的,并且完全受控于当前组件。
  • 无需使用state的情况下可省略constructor
  • 构造函数是唯一可以对this.state赋值的地方,其他场合仅可使用this.setState()(类似wx小程序)
class Clock extends React.Component {
  constructor(props) {
    super(props);
    this.state = {date: new Date()};
  }
  componentDidMount() {
    this.timerID = setInterval(
      () => this.tick(),
      1000
    );
  }

  componentWillUnmount() {
    clearInterval(this.timerID);
  }

  tick() {
    this.setState({
      date: new Date()
    });
  }

  render() {
    return (
      <div>
        <h1>Hello, world!</h1>
        <h2>It is {this.state.date.toLocaleTimeString()}.</h2>
      </div>
    );
  }
}

ReactDOM.render(
  <Clock />,
  document.getElementById('root')
);
  • 出于性能考虑,React 可能会把多个 setState() 合并成一个,因此setState()可能是异步的,this.propsthis.state 可能会异步更新,setState()时不要直接使用他们的值,而是用一个函数作为入参
this.setState((state, props) => ({
  counter: state.counter + props.increment
}));
//或
this.setState(function(state, props) {
  return {
    counter: state.counter + props.increment
  };
});
自上而下的单向数据流

多重组件嵌套时,通常将父的state传递给子的props,任何的 state总是所属于特定的组件,而且从该 state 派生的任何数据或 UI 只能影响树中“低于”它们的组件。


事件处理

React 事件的命名采用小驼峰式而非纯小写,且在JSX中需传入一个事件处理函数。

function ActionLink() {
  function handleClick(e) {
    e.preventDefault();
    console.log('The link was clicked.');
  }

  return (
    <a href="#" onClick={handleClick}>
      Click me
    </a>
  );
}
  • 事件的默认参数e已做过跨浏览器兼容处理,直接使用 e.preventDefault();即可统一阻止默认事件。
使用class组件时的方法内this指向问题

可类比以下操作

class A {
  handleClick1 = () => {
    console.log(this, "handleClick1");
  }
  handleClick2() {
    console.log(this, "handleClick2");
  }
  render() {
    window.addEventListener("click", this.handleClick1);//A
    window.addEventListener("click", this.handleClick2);//window
  }
}
new A().render();

因此有三种方法避免this指向问题

  1. 构造函数中使用bind
  constructor(props) {
    super(props);
    this.handleClick = this.handleClick.bind(this);
  }
  1. 使用class fields语法
  handleClick = () => {
    console.log(this);
  }
  1. 在回调中使用()=>bind
  • ()=>
<button onClick={(e) => this.handleClick(id, e)}>Click me</button>
  • bind
handleClick(id,event){
  ...
}
<button onClick={this.handleClick.bind(this, id)}>Click me</button>

条件渲染

当不想进行任何渲染时,可以return null

&&
function Mailbox(props) {
  const unreadMessages = props.unreadMessages;
  return (
    <div>
      <h1>Hello!</h1>
      {unreadMessages.length > 0 &&
        <h2>
          You have {unreadMessages.length} unread messages.
        </h2>
      }
    </div>
  );
}

?:
render() {
  const isLoggedIn = this.state.isLoggedIn;
  return (
    <div>
      The user is <b>{isLoggedIn ? 'currently' : 'not'}</b> logged in.
    </div>
  );
}

列表 & Key

列表中的内容是一个React元素的数组,以下两种方式均可生成一个列表
注意列表中必须有key,未指定key时key默认为索引值

function NumberList(props) {
  const numbers = props.numbers;
  const listItems = numbers.map((number) =>
    <ListItem key={number.toString()}
              value={number} />
  );
  return (
    <ul>
      {listItems}
    </ul>
  );
}
function NumberList(props) {
  const numbers = props.numbers;
  return (
    <ul>
      {numbers.map((number) =>
        <ListItem key={number.toString()}
                  value={number} />
      )}
    </ul>
  );
}

表单

React中未实现双向绑定

受控组件
class Reservation extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      isGoing: true,
      fruit: "lime"
    };

    this.handleChange= this.handleChange.bind(this);
  }

  handleChange(event) {
    const target = event.target;
    const value = target.name === 'isGoing' ? target.checked : target.value;
    const name = target.name;
    this.setState({
      [name]: value
    });
  }

  render() {
    return (
      <form>
          <input
            name="isGoing"
            type="checkbox"
            checked={this.state.isGoing}
            onChange={this.handleChange} />

          <select name="fruit" value={this.state.fruit} onChange={this.handleChange}>
            <option value="grapefruit">葡萄柚</option>
            <option value="lime">酸橙</option>
            <option value="coconut">椰子</option>
            <option value="mango">芒果</option>
          </select>
      </form>
    );
  }
}
非受控组件
  • 当 ref 属性用于 HTML 元素时,构造函数中使用 React.createRef() 创建的 ref 接收底层 DOM 元素作为其 current 属性。
  • 当 ref 属性用于自定义 class 组件时,ref 对象接收组件的挂载实例作为其 current 属性。
class FileInput extends React.Component {
  constructor(props) {
    super(props);
    this.handleSubmit = this.handleSubmit.bind(this);
    this.fileInput = React.createRef();
  }
  handleSubmit(event) {
    event.preventDefault();
    alert(
      `Selected file - ${this.fileInput.current.files[0].name}`
    );
  }

  render() {
    return (
      <form onSubmit={this.handleSubmit}>
        <label>
          Upload file:
          <input type="file" ref={this.fileInput} />
        </label>
        <br />
        <button type="submit">Submit</button>
      </form>
    );
  }
}

ReactDOM.render(
  <FileInput />,
  document.getElementById('root')
);
使用 Formik

状态提升

将多个组件中需要共享的 state 向上移动到它们的最近共同父组件中,以实现共享 state

实现方式

父元素通过props将待展示的值和该值变化时的回调方法传给子元素。子元素调用该回调时,父元素对应state改变,并重新影响各个子元素。以此实现兄弟元素间的值共享。


打包

在package.json中加入"homepage": ".",即可使打包后资源路径变为相对路径(否则默认为绝对路径)。

相关文章

  • react native 基础知识点

    Hello World react native 官方Hello world示例 我们从import开始来看这个程...

  • React网址

    React文档: https://react.docschina.org/docs/hello-world.html

  • React的Hello World

    VSCode配置语法高亮 安装Babel JavaScript插件 创建项目 其他还有 npm run build...

  • 用React Native开发一个应用

    在React Native中创建“Hello World”程序 创建项目 使用Xcode 使用模拟器 React基...

  • React

    官方文档 https://react.docschina.org/docs/hello-world.html 一....

  • 常用markdown语法

    Hello World! Hello World! Hello World! Hello World! Hello...

  • hello

    hello, world hello, world hello, world hello, world

  • [React] Hello world(2)

    1. 简单的Hello world示例 ReactDOM.render()是React的最基本方法用于将模板转为H...

  • react文档——Hello World

    Hello World 最容易开始使用 React 方式是用CodePen。你不需要安装任何东西;你只需要在新页面...

  • react之Hello World

    背景 Facebook 为了开发一套更好更适合自己的JavaScript MVC 框架,所以产生了react。后来...

网友评论

      本文标题:React的Hello World

      本文链接:https://www.haomeiwen.com/subject/ynqpnhtx.html