如何将React代码拆分为两个文件且无需重复编写相同逻辑?
React 组件拆分方案
拆分思路
- 逻辑层:将所有 state 定义、事件处理函数封装为自定义 Hook,单独存放为一个文件,只向 UI 层暴露需要用到的状态与方法
- 视图层:仅保留组件渲染逻辑,引入封装好的自定义 Hook 获取数据和方法,完成页面渲染
第一步:新建状态与处理逻辑文件 useUserInput.js
import { useState } from "react"; export default function useUserInput() { const [person, setPerson] = useState({firstName:'', age:''}); const [people, setPeople] = useState([]); const handleChange = (e) => { const name = e.target.name; const value = e.target.value; setPerson({...person, [name]: value}); } const handleSubmit = (e) => { e.preventDefault(); if(person.firstName && person.age){ // 注:原代码中使用new Date().getDate()生成id会出现同一天提交的记录id重复的问题,这里优化为生成毫秒级时间戳作为唯一id const newPerson = {...person, id: new Date().getTime().toString()} setPeople([...people, newPerson]); setPerson({firstName:'', age:''}); } else{ console.log('Empty field!') } } const handleDelete = () => { setPeople([]); setPerson({firstName:'', age:''}); } // 向外部暴露需要用到的状态和方法 return { person, people, handleChange, handleSubmit, handleDelete } }
第二步:新建页面渲染组件文件 UserInput.jsx
import useUserInput from './useUserInput'; import './style.css'; export default function UserInput() { // 从自定义Hook中获取所需状态和方法 const { person, people, handleChange, handleSubmit, handleDelete } = useUserInput(); return( <> <form className='container' autoComplete="off"> <div> <label htmlFor='firstName' className='label'>Name: </label> <input type='text' className='input' id='firstName' name='firstName' value={person.firstName} onChange={handleChange}/> <br/> <label htmlFor='age' className='label'>Age: </label> <input type='text' className='input-age' id='age' name='age' value={person.age} onChange={handleChange}/> <br/> <button className= 'btn' type='submit' onClick={handleSubmit}>Add</button> <button className= 'btn' type='button' onClick={handleDelete}>Clear</button> </div> </form> { people.map((person)=>{ return( <div className='list' key={person.id}> {person.firstName}, {person.age} </div> ) }) } </> ); }
拆分后逻辑层和视图层完全解耦,后续如果要修改表单逻辑只需要调整useUserInput.js,修改页面样式只需要调整UserInput.jsx,维护成本更低。
内容的提问来源于stack exchange,提问作者SolidOpt
相关产品推荐
相关产品推荐

