认识React

23 阅读3分钟

1、创建React项目

使用脚手架create-react-app

npx create-react-app react-demo

2、函数组件只能返回一个根元素

函数组件只能返回一个根元素,如果想要返回多个根元素,可以使用<Fragment></Fragment>标签(等价于<></>),这是一个虚拟标签,最终不会被渲染到页面上。

return 后面返回的标签,不管是单行还是多行,最好都要加上括号(单行不加也不会报错,多行不加会出错)。

function Example () {
  return (
    <>
       <div className="one"></div>
       <div className='two'></div>
    </>
  );
}

3、插值

(1)条件渲染

import logo from './logo.svg'
import './App.css'

function App() {
  let flag = true
  let mark = false
  let divContent = null

  if (mark) {
    divContent = <div>true mark</div>
  } else {
    divContent = <div>false mark</div>
  }

  return (
    <div className="App">
      <header className="App-header">
        // 直接使用logo变量、三目运算符、定义的变量
        <img src={logo} className="App-logo" alt="logo" />
        {flag ? <div>true flag</div> : <div>false flag</div>}
        {divContent}
      </header>
    </div>
  )
}

export default App

(2)列表渲染

import { Fragment } from 'react'
import './App.css'

function App() {
  const list = ['one', 'two', 'three']

  const listContent = list.map((item, index) => (
    <Fragment key={index}>
      <li>{item}</li>
      <li>{`${item}附加内容`}</li>
    </Fragment>
  ))
  return (
    <div className="App">
      <div>{listContent}</div>
    </div>
  )
}

export default App

4、状态处理

vue实现了双向响应,数据发生变化之后,视图会自动更新。但是react在数据发生变化之后,视图并不会更新,需要我们自己更新视图。

使用useState改变状态,更新视图。

import { Fragment, useState } from 'react'
import './App.css'

function App() {
  const [list, setList] = useState(['one', 'two', 'three'])

  const listContent = list.map((item, index) => (
    <Fragment key={index}>
      <li>{item}</li>
      <li>{`${item}附加内容`}</li>
    </Fragment>
  ))

  const handleClick = () => {
    // 不管是对象还是数组,都需要重新整个赋值
    setList([...list, 'four'])
  }

  return (
    <div className="App">
      // 如果是对象obj,直接在{}中使用对象会报错,可以选择使用对象属性在视图上展示
      <div>{listContent}</div>
      <button onClick={handleClick}>点击</button>
    </div>
  )
}

export default App

5、DOM组件

DOM组件HTML的标签很像,但是React做了一定的处理,我们可以低成本的像HTML标签那样直接使用,也可以使用一些特定的组件属性classNamestyle...展开运算符

<img
	src={logo}
	className="App-logo"
	style={{ width: 100, height: 100 }}
	alt="logo"
/>

也可以将style样式放在对象里

function App() {
  const imgStyleObject = { width: 100, height: 100 }
  return (
    <div className="App">
      <img src={logo} className="App-logo" style={imgStyleObject} alt="logo" />
    </div>
  )
}

使用jsx的展开语法

function App() {
  const imgStyleObject = { width: 100, height: 100 }
  const imgData = { className: 'App-logo', style: imgStyleObject }
  return (
    // {...imgData} 这里的{}并不是...运算符的容器,是jsx的一种语法标记,对于扩展运算符,React做了额外的处理
    <div className="App">
      <img src={logo} alt="logo" {...imgData} />
    </div>
  )
}

6、React组件

通过props传递参数,可以结合扩展运算符让DOM组件变得简洁

function Deatil ({ content }) {
  return <div>{content}</div>
}

function Article({ title, detailData }) {
  return (
    <>
      <div>{title}</div>
      <Deatil {...detailData}></Deatil>
    </>
  )
}

function App() {
  const articleDate = {
    title: '标题',
    detailData: {
      content: '内容',
    },
  }
  return <Article {...articleDate}></Article>
}

7、将JSX作为props传递给子组件

类似于vue中的插槽功能,将组件中间的内容传递给子组件,子组件使用children接收。

function List({ children }) {
  return <>{children}</>
}
function App() {
  return (
    <List>
      <li>1</li>
      <li>2</li>
      <li>3</li>
    </List>
  )
}

8、子组件调用父组件传递过来的事件

通过props将事件属性onActive直接传递给子组件,子组件进行调用,可以通过函数向父组件传递值。

function List({ onActive }) {
  const handleClick = () => {
    onActive(true)
  }
  return (
    <>
      <button onClick={handleClick}>Click me!</button>
    </>
  )
}
function App() {
  const handleActive = (status) => {
    window.alert(status)
  }
  return <List onActive={handleActive}></List>
}

9、同级组件之间的数据传输

可以通过父组件进行中转,也就是说将数据定义在父组件中,分别传递到两个子组件中同级组件通过父组件中转传递数据

10、Context 多级组件传值

卡颂 - Context

const ctx = createContext(null);

function App() {
	return (
		<ctx.Provider value={1}>
			<Cpn />
		</ctx.Provider>
	);
}

function Cpn() {
	const num = useContext(ctx);
	return <div>{num}</div>;
}

11、hooks

React 全部 Hooks 使用大全

Reducer:统一管理状态的操作方式

useRef:记录组件更新之前的值

useEffect:严格模式下,Effect中的函数默认执行2次,检查组件内的函数是否是纯函数

useMemo:缓存数据

useCallback:缓存函数

mome:缓存组件,如果组件接收的props没有发生变化,就不会受到父组件更新的影响。

如果传递给组件一个函数,那么可以使用useCallback包裹这个函数,使得父组件更新时,函数不会相应的更新,导致子组件的更新同步被触发。