React中如何点击按钮填充输入框?附代码求解决方案
实现点击按钮填充文本到输入框的方案
要实现点击建议按钮将文本填充到输入框的功能,核心是让按钮组件和输入框组件共享状态,通过状态提升到共同父组件来实现数据传递。以下是具体修改步骤:
1. 修改App.js:提升状态到根组件
将输入框的title状态和修改方法setTitle放到App组件中,作为全局可传递的状态:
import { useState } from 'react'; // 其他导入保持不变 function App() { const [suggestiveListBorder, setSuggestiveListBorder] = useState(""); // 添加输入框的状态管理 const [inputTitle, setInputTitle] = useState(""); return ( <div className="App"> <Navbar /> {/* 传递setInputTitle给ListOfExercises */} <ListOfExercises suggestiveListBorder={suggestiveListBorder} setInputTitle={setInputTitle} ></ListOfExercises> <div className="pages"> <Routes> <Route path="/" element={<Home />} /> <Route path="/chest" element={ <ChestWorkouts setSuggestiveListBorder={setSuggestiveListBorder} inputTitle={inputTitle} setInputTitle={setInputTitle} /> } /> <Route path="/hamstrings" element={<HamstringsWorkouts />} /> {/* 其他路由保持不变 */} </Routes> </div> </div> ); }
2. 修改ListOfExercises.js:传递setInputTitle给子组件
把App传递来的setInputTitle继续传递给ChestExosList:
export function ListOfExercises({ suggestiveListBorder, setInputTitle }) { const currentLocation = useLocation(); let currentLocat = currentLocation.pathname; const chestExos = exercisesData.exercises.chest_Exercises; return ( <> {currentLocat === "/chest" ? ( <ChestExosList suggestiveListBorder={suggestiveListBorder} chestExos={chestExos} setInputTitle={setInputTitle} // 传递方法 /> ) : currentLocat === "/hamstrings" ? ( <span>hamstrings</span> ) : null} </> ); }
3. 修改ChestExosList.js:给按钮添加点击事件
在循环生成的按钮上添加onClick事件,点击时将按钮文本设置到输入框状态:
export function ChestExosList({ chestExos, suggestiveListBorder, setInputTitle }) { const chestValues = Object.values(chestExos); return ( <div className="chest-exos-list-container" style={{ border: suggestiveListBorder, }} > <div> <p className="chest-exos-paragraph"> Have no idea about the exercise you want to do ? Here are some suggestions : </p> </div> <Stack direction="row" spacing={2} sx={{ marginBottom: "30px" }}> {chestValues.map( (elem, index) => index < 8 && index >= 0 && ( <Button type="secondary" key={index} onClick={() => setInputTitle(elem)} // 添加点击事件 > {elem} </Button> ) )} </Stack> {/* 其他内容保持不变 */} </div> ); }
4. 修改Chest页面:传递状态到WorkoutForm
将App传递来的inputTitle和setInputTitle传递给WorkoutForm:
const Chest = ({ setSuggestiveListBorder, inputTitle, setInputTitle }) => { const { workouts, dispatch } = useWorkoutsContext(); useEffect(() => { const fetchWorkouts = async () => { const response = await fetch("/api/workouts"); const json = await response.json(); if (response.ok) { dispatch({ type: "SET_WORKOUTS", payload: json }); } }; fetchWorkouts(); }, [dispatch]); const antIcon = ( <LoadingOutlined style={{ fontSize: 50, }} /> ); return ( <div className="chest-page-container"> <div className="chest-page-workouts"> {!workouts && <Spin spinning={true} indicator={antIcon}></Spin>} {workouts && workouts.map((workout) => ( <WorkoutDetails workout={workout} key={workout._id} /> ))} </div> {/* 传递状态和方法 */} <WorkoutForm setSuggestiveListBorder={setSuggestiveListBorder} title={inputTitle} setTitle={setInputTitle} /> </div> ); };
5. 修改WorkoutForm.js:使用父组件传递的状态
移除WorkoutForm中本地的title状态,改用父组件传递来的title和setTitle:
// 移除本地的useState定义:const [title, setTitle] = useState(""); export function WorkoutForm({ setSuggestiveListBorder, title, setTitle }) { // 其他逻辑保持不变,比如handleSubmit、emptyFields等 return ( <form className="chest-workouts-form" onSubmit={handleSubmit}> <div className="chest-workouts-form-inner"> <h3>Add a New Workout</h3> <label>Excercise Title : </label> <input onMouseOver={() => { setSuggestiveListBorder("1.5px solid #1aac83"); }} type="text" onChange={(e) => setTitle(e.target.value)} value={title} // 使用父组件传递的状态 className={emptyFields.includes("title") ? "form-msg-error" : ""} /> {/* 其他表单元素保持不变 */} </div> </form> ); }
核心逻辑说明
- 通过将输入框的状态提升到App组件,让按钮和输入框共享同一个状态源
- 点击按钮时调用
setInputTitle更新状态,输入框会自动同步显示最新值 - 所有组件通过props传递状态和修改方法,保证数据流的一致性
内容的提问来源于stack exchange,提问作者Abdelmounim SIFELHAK
相关产品推荐
相关产品推荐

