react hooks 开发小结

340 阅读3分钟

此文章主要把近段时间使用react hooks开发遇到的一些问题和解决方法记录一下

一.使用样式的方法

方法1.当前页面定义样式

const btnStyle = {
	width:'100%',
    display: 'flex',
    alignItems: 'center',
    justifyContent: 'center'
}  

<Button style={btnStyle}></Button>

方法2.引入样式

import '../style.less'  
<Button className='btnStyle'></Button>

方法3.行内样式

<Button style={{width: '100%'}}></Button>

二.组件传参和方法调用

// 伪代码
// 父组件
export default function FatherPage() {
	const [age, setAge] = useState<number>(12)
    const handleReload = (data) => {
        console.log(data) // 子组件传递过来的数据
    }
    
	return (
          <div>
              <ChildPage age={age} onResult={() => handleReload()}></ChildPage>
          </div>
    )

}
// 子组件
const ChildPage = (props) => {
	console.log(props) // 这里可以获取到父组件传递过来的数据和方法
    
    const handleClick = () => {
        // 触发父组件的onResult方法,并且可以传参过去
        props.onResult({   
            name: '张三',
            age: 20
        })
    }
	return (
          <div>
              我是子组件 { props.age }
              <Button onClick={() => handleClick()}>按钮<Button>
          </div>
    )
}

export default ChildPage

三.改变数组和对象属性注意事项

直接更改数组或对象属性是无效的,因为其引用地址不会变,react不会重新加载

正确更改方式是复制引用,然后整个替换

 // 伪代码
 const [nodeObj, setNodeObj] = useState<any>({
      age: 20,
      name: '李四'
 })
 
 // 更新对象 使用扩展运算符创建一个全新的引用(副本),并设置一个新值
 setNodeObj({...nodeObj, age: 10})
 
 // 更新数组
 const [array, setArray] = useState([
        {'id': 0, text: '0'},
        {'id': 1, text: '1'},
        {'id': 2, text: '2'}
 ])
const copy = [...array]
// or => const copy = Array.from(array) 
copy[2].text = '3'
setArray(copy)

四.hooks的钩子函数

// useState 返回一个 state,以及更新 state 的函数
const [age, setAge] = useState<number>(10)

// useEffect 可以监听数据的改变然后执行某些操作
useEffect(() => {
    console.log(1111)
}, [nodeObj.id])

// useMount 进来时初始化数据
  useMount(() => {
    initData()
  })

// useContext   跨层级传参

const itemObj = [
   light:{
        color: '#fff',
        background: '#1890ff'
    },
    dark: {
    	color: '#fff',
      	background: '#0c0c0c'
    }
]

const objContext = React.createContext(itemObj.dark) // 可以设置默认值

// 祖先组件
function App() {
  return (
    <ObjContext.Provider value={itemObj.light}>
      <FatherPage />
    </ObjContext.Provider>
  );
}

// 父组件
function FatherPage(props) {
  return (
    <div>
      <ChildPage />
    </div>
  )
}

// 子组件
function ChildPage(props) {
    const theme = useContext(objContext) // 这里获取祖先组件传递的数据 
    return (
      <button style={{ background: theme.background, color: theme.color }}>
      	useContext
      </button>
  );
}

以上几个是较为常用的钩子函数,还有useReducer,useCallback,useMemo,useRef,useImperativeHandle,useLayoutEffect,useDebugValue等有时间我会再写,或者各位感兴趣可以自己去了解

五.jsx里面的循环和判断

// 伪代码  (或者使用三目运算符,也可以在函数外部判断)
const dateList = [
  {
    value: 'permanent',
    label: '永久'
  },
  {
    value: 'year',
    label: '一年'
  },
  {
    value: 'month',
    label: '一月'
  },
  {
    value: 'week',
    label: '一周'
  },
  {
    value: 'day',
    label: '一天'
  }
]
{
	{ type === 'custom' &&  (
       <Select style={{ width: '300px' }} value="week" >
          { dateList.map(item => {
            return (
              <Select.Option value={item.value} key={item.value}>
                {item.label}
              </Select.Option>
            )
          }) }
    	</Select>
    )
}

六. 父组件通过ref获取子组件的值或者方法

	//父组件
    import React, {useState, useEffect, useImperativeHandle, forwardRef} from 'react'
    
    export default function Father() {
     	const childRef:any = useRef()
        
        const handleClick = () => {
        	console.log(childRef.current.formValues) //获取子组件的值
            childRef.current.cleanForm()  // 调用子组件的方法
        }
        
        return (
        	<Button onClick={handleClick}></Button>
        	<Child ref="childRef" />
        )
    }
    	 
          
    //子组件
    const Child = (props: modalProps, ref: any) => {
        const [checked, setChecked] = useState<boolean>(true)
        useImperativeHandle(ref, () => ({
            formValues: {
              checked
            },
             cleanForm: () => {
               setChecked(true)
             }
        }))

        const onChange = (checked: boolean) => {
            setChecked(checked)
        }
        return (
            <div>
                 <Switch defaultChecked onChange={onChange} checked={checked} />
            </div>
        )
    }
    
    export default forwardRef(Child)

七. 封装组件

// 封装一个带form的modal  
import React, {useState, useEffect, useImperativeHandle, forwardRef} from 'react'
import { Form, Modal, Input } from 'antd'

interface modalProps {
  width? : string | number, // 宽度
  title?: string, // 标题
  visible : boolean, // 是否隐藏
  okText?: string, // 确定文字
  cancelText?: string, // 取消按钮文字
  handleCancel?: () => void // 取消方法
  handleOk?: () => void // 确定方法
}

const ModalForm = (props: modalProps, ref: any) => {
  const { title, width='600px', visible, handleCancel, handleOk, okText='确定', cancelText= '取消'} = props
  const [form] = Form.useForm()

  useEffect(() => {
   form.resetFields()
  },[visible])

  useImperativeHandle(ref, () => ({
    getForm: () => form
  }))

  const layout = {
    labelCol: { style: {
      width: '120px'
    }}
  };
  return (
    <>
      <Modal
        width={width}
        title={title}
        onCancel={handleCancel}
        visible={visible}
        onOk={handleOk}
        okText={okText}
        cancelText={cancelText}
      >

          <Form {...layout} form={form} >
            <Form.Item name="username" label="用户名" rules={[{ required: true, message: '请输入用户名' }]}>
              <Input placeholder="用户名"/>
            </Form.Item>
            <Form.Item name="pwd" label="密码" rules={[{ required: true, message: '请输入密码' }]}>
              <Input type="password" placeholder="密码"/>
            </Form.Item>
        </Form>
      </Modal>
     </>
  )
}

export default forwardRef(ModalForm)
    
 // 使用ModalForm组件
import ModalForm from './ModalForm'
const handleOk = () => {
    console.log(refModal.current.getForm())  // 这里可以获取useForm的所有方法
}

export default function UseModal() {
 const [visible, setVisible] = useState<boolean>(false)
 const refModal:any = useRef()
    return (
        <>
         <ModalForm ref={refModal} visible={visible} title="表单弹框" handleCancel={() => setVisible(false)}  handleOk={handleOk} />
        </>
    )
}
	

有问题的地方欢迎指正