美文网首页
react16.8 hook

react16.8 hook

作者: 春饼sama | 来源:发表于2019-02-19 18:04 被阅读0次

最近在学Vue,很久没用react写东西了,今天来学习一下16.8的hook
官网 科学上网看小哥哥写代码
亲自写写

useState

useState主要用于解决函数式组件没有状态

import React,{useState} from "react";

function App() {
  const [count, setCount] = useState(0);
  function addCount(){
    setCount(count+1)
  }
  return (
    <div>
      <p>You clicked {count} times</p>
      <button onClick={addCount}>
        Click me
      </button>
    </div>
  );
}

ps:不要在if或者else里面使用

useContext

之前我们使用context来解决多层嵌套传props,分三步

  1. createContext创建Context
  2. 使用Context.Provider组件提供数据
  3. Context.Provider的所有后代组件,都可以通过Context.Consumer使用数据数据
const ColorContext = React.createContext('black')

function Button(props){
    return (
      <ColorContext.Consumer>
      {color=>
        <button style={{ background: color }}>
          {color,props.children}
        </button>}
      </ColorContext.Consumer>
      
    );
}

function MiddleWare(){
  return (
    <Button>我来了</Button>
  )
}

function App() {
  return (
    <div>
      <ColorContext.Provider value='yellow'> 
        <MiddleWare></MiddleWare>
      </ColorContext.Provider>
    </div>
  );
}
useContext方案

不再需要consumer,useContext接收一个createContext()返回的对象

function Button2(props){
  const color = useContext(ColorContext)
  return <button style={{ background: color }}>{(color, props.children)}</button>
}

可以提供Provider以改变传值

function MiddleWare(props) {
  return 
    <ColorContext.Provider value="yellow">
        <Button2>指定provider</Button2>
    </ColorContext.Provider>
}

example

useEffect

useEffect的作用是依赖变化的时候,执行函数,其中第二个参数为依赖

function App() {
 const [width,setWidth] = useState(window.innerWidth)
  useEffect(()=>{
    const handleResize = () => setWidth(window.innerWidth)
    window.addEventListener('resize',handleResize)
    return ()=>{
      window.removeEventListener('resize',handleResize)
    }
  })
  return (
    <div>
      <p>{width}</p>
    </div>
  )
}

useEffect相当于合并了componentDidMount和componentDidUpdata和componentWillUnmount

  componentDidMount(){
   window.addEventListener('resize',this.handleResize)
  }
  componentDidUpdate(){
   window.addEventListener('resize',this.handleResize)
  }
  componentWillUnmount(){
  window.removeEventListener('resize',this.handleResize)
}
  handleResize(){
  this.setState({width:window.innerWidth})
}

然后可以把Effect抽离出来做为函数,代码可复用

function useWidth(){
  const [width, setWidth] = useState(window.innerWidth)
  useEffect(() => {
    const handleResize = () => setWidth(window.innerWidth)
    window.addEventListener('resize', handleResize)
    return () => {
      window.removeEventListener('resize', handleResize)
    }
  })

  return width
}

function App() {
 const width =  useWidth()
  return (
    <div>
      <p>{width}</p>
    </div>
  )
}

example

最后实践一下

写一个useOutsideClick

function useOutsideClick(ref, fnc) {
  useEffect(() => {
    const handleClickOutside = e => {
      if (e.target !== ref.current && !ref.current.contains(e.target)) {
        fnc();
      }
    };
    window.addEventListener("click", handleClickOutside);
    return () => {
      window.removeEventListener("click", handleClickOutside);
    };
  }, [ref, fnc]);
}

使用(非常的简单):

function App() {
  const ref = useRef(null);
  useOutsideClick(ref, () => {
    console.log('OUTSIDE CLICKED');
  });

  return (
    <div ref={ref} style={{
      width: 200,
      height: 200,
      background: 'red',
    }} />
  );
}

demo

useReducer

让我们来回忆一下 使用redux使用reducer

1.首先创建一个store index.store.js
export default function configStore(){
    const store = createStore(rootReducer,applyMiddleware(...middlewares))
    return store
}

2.引入store app.js
  render() {
    return (
      <Provider store={store}>
        <Index />
      </Provider>
    )
  }

3.定义action和创建reducder index.action.js index.reducer.js
export const ADD = 'ADD'
export const DELETE = 'DELETE'
function todos(state = INITAL_STATE, action) {
  switch action.type{
    case ADD:{...}
    case DELETE:{...}
  }
}

4.页面中使用reducer  component.js
export default connect(mapStateToProps, mapDispatchToProps)(Component);

太复杂了有没有,(使用dva可以简化写法)
而使用useReducer可以省略很多代码:

//index.js
  const { state, dispatch } = useContext(reducerContext);
  return (
    <div className="App">
      <>
        Count: {state.count}
        <button
          onClick={() => dispatch({ type: "reset", payload: { count: 0 } })}
        >
          Reset
        </button>
        <button onClick={() => dispatch({ type: "increment" })}>+</button>
        <button onClick={() => dispatch({ type: "decrement" })}>-</button>
        <reducerContext.Provider value={{ state, dispatch }}>
          <ChangeCount />
        </reducerContext.Provider>
      </>
    </div>
  );

不过useReducer不支持共享数据,推荐使用redux-react-hook,同样是通过context实现的redux
但是不知是否有像查看store的浏览器插件,或者redux-logger这样的中间件帮助我们查看状态的变化,redux的生态还是更好一点的
demo

相关文章

  • Hook

    hook 介绍 Hook 是 React16.8 的新特性。Hook 就是 JavaScript 函数, 它可以让...

  • react16.8 hook

    最近在学Vue,很久没用react写东西了,今天来学习一下16.8的hook官网 科学上网看小哥哥写代码亲自写写 ...

  • React Hook

    Hook 是能让你在函数组件中“钩入” React 特性的函数(hook是react16.8的新增特性,让函数组件...

  • useState原理以及其它react-hook的使用

    前言 自react16.8发布了正式版hook用法以来,我们公司组件的写法逐渐由class向函数式组件+hook的...

  • ReactHook快速上车

    React16.8开始内置了10个Hook,核心是2个: 状态管理:useState 副作用管理:useEffec...

  • React-Hook

    react hook必须在react16.8版本以上才能使用 1.useState 官网对useEffect的介绍...

  • React Hooks

    ReactHooks Hook(钩子) 是React16.8的新增特性。它可以让你在不编写class的情况下使用s...

  • react的Hook-09

    Hook是React16.8的新增特性。它可以让你在不编写class的情况下使用state以及其他的react特性...

  • React函数式编程之HOOK

    Hooks Hook是 React16.8 的新特性,可以在不使用类组件的情况下,使用 state 以及其他的Re...

  • React Hooks入门

    React Hook 是React16.8提出来的一个新特性,其意义就在于我们可以让函数组件变得跟类组件一样有能力...

网友评论

      本文标题:react16.8 hook

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