React组件传参问题:重构后如何从<App>向<TextBox>传递props?
Hey there! Sounds like you've made great progress with your React app—refactoring to use Bootstrap for side-by-side layout is a solid move. Let's break down the correct way to get that prop passing from <App> to <TextBox> working smoothly now that your component structure has shifted.
Core Idea: State Lift-Up
Since <FileTree> and <TextBox> are now sibling components under <App>, we need to lift the shared state up to their common parent (App). This way, App acts as the single source of truth for data that needs to be shared between the two components, and can pass it directly to <TextBox> while letting <FileTree> trigger updates to that state.
Step 1: Manage Shared State in
First, define the state you want to pass to <TextBox> in <App>, plus a callback function to update that state (so <FileTree> can send selected file data up to App). Here's how that looks for a functional component:
import { useState } from 'react'; import FileTree from './FileTree'; import TextBox from './TextBox'; function App() { // State to hold content that will be passed to TextBox const [selectedContent, setSelectedContent] = useState(''); // Callback for FileTree to trigger when a file is selected const handleFileSelect = (content) => { setSelectedContent(content); }; return ( <div className="container mt-4"> <div className="row"> {/* Pass the callback to FileTree so it can update App's state */} <div className="col-md-6"> <FileTree onFileSelect={handleFileSelect} /> </div> {/* Directly pass the state as props to TextBox */} <div className="col-md-6"> <TextBox content={selectedContent} /> </div> </div> </div> ); } export default App;
Step 2: Update to Receive Props
Make sure <TextBox> accepts and uses the props passed from <App>. For a functional component, this is straightforward:
// TextBox.js function TextBox({ content }) { return ( <div className="card"> <div className="card-header">File Content</div> <div className="card-body"> {/* Use the passed content prop */} <textarea className="form-control" value={content} rows="10" readOnly /> </div> </div> ); } export default TextBox;
Step 3: Adjust to Trigger the Callback
Update <FileTree> to call the callback function from <App> when a file is selected, passing along the content you want to send to <TextBox>:
// FileTree.js function FileTree({ onFileSelect }) { // Replace with your actual file structure/data const files = [ { name: 'README.md', content: '# My Project\nThis is a sample README' }, { name: 'App.js', content: 'import React from "react";\nfunction App() { ... }' } ]; const handleFileClick = (file) => { // Call the callback to update App's state with the selected file content onFileSelect(file.content); }; return ( <div className="card"> <div className="card-header">File Tree</div> <ul className="list-group list-group-flush"> {files.map((file, index) => ( <li key={index} className="list-group-item" onClick={() => handleFileClick(file)} style={{ cursor: 'pointer' }} > {file.name} </li> ))} </ul> </div> ); } export default FileTree;
Why This Works
Before your refactor, <FileTree> was directly passing props to <TextBox>, but now they're siblings. By lifting the state to <App>, we follow React's one-way data flow:
<App>holds the shared data<FileTree>notifies<App>when data needs to change<App>automatically passes the updated data down to<TextBox>
This makes your code easier to debug and maintain, since there's only one place where the shared state lives.
内容的提问来源于stack exchange,提问作者RCohen

