如何将道具从 child 组件传递到 parent 组件到 ReactJS 中的另一个 child 组件?
How to pass props from child component to parent component to another child component in ReactJS?
我目前正在创建一个搜索栏,其中 App
是 parent,Header
,Home
是 children。我试图通过 App
将输入从 Header
传递到 Home
,但似乎当我尝试加载 {this.state.searchValue}
时它什么也没做。
我不知道我的代码哪里出错了。我还使用 Route
将道具从 Header
路由到 Home
。
这是我的代码:
Header.js (Child 1)
class Header extends Component {
constructor(props) {
super(props);
this.state = {
search: "",
};
}
onChange = (event) => {
this.setState({ search: event.target.value });
};
submitSearch = (event) => {
event.preventDefault();
console.log(this.state.search);
this.props.passSearchData(this.state.search);
};
render() {
return (
<React.Fragment>
<nav className="navbar navbar-expand-lg navbar-light bg-light">
<form className="form-inline">
<input
className="form-control mr-sm-2"
type="text"
placeholder="Search"
onChange={this.onChange}
/>
<button
className="btn btn-danger"
type="submit"
onClick={this.submitSearch}
>
Search
</button>
</form>
</nav>
</React.Fragment>
);
}
}
export default Header;
App.js (Parent)
class App extends Component {
constructor() {
super();
this.state = {
searchValue: "",
};
}
handleSearchData = (search) => {
this.setState({ searchValue: search });
};
componentDidMount() {
this.props.getItems();
}
render() {
return (
<div className="App">
<Router>
<Header passSearchData={this.handleSearchData} />
<Route
exact
path="/"
render={(props) => (
<Home {...props} searchValue={this.state.searchValue} />
)}
/>
</Router>
<Footer />
</div>
);
}
}
Home.js
class Catalog extends Component {
constructor(props) {
super(props);
this.state = {
};
}
render() {
return (
<div>
<p>{this.props.searchValue}</p>
</div>
);
}
}
我认为使用 React 上下文更好地解决这个问题,因为在路由之间传递状态非常痛苦
首先你声明你自己的提供者作为组件之间的中介。
上下文将保存所有应用程序状态。并使用您的组件,只需使用 useContext
并传递您想要使用的上下文,在这个用例中,我称之为 AppContext
。通过使用相同的上下文,您的组件会获得相同的状态并立即触发更新
我提供的解决方案是使用功能组件。如果您正在使用 class 组件,只需简单地创建一个功能组件,然后将上下文传递给 class 组件
import React, { useContext, useState } from 'react'
const AppContext = React.createContext({})
const AppProvider = props => {
const [currentState, setCurrentState] = useState(null)
const handleState = value => {
setCurrentState(value)
}
const contextValue = { handleState, currentState }
return (
<AppContext.Provider value={contextValue}>
{props.children}
</AppContext.Provider>
)
}
const Child1 = props => {
const { handleState } = useContext(AppContext)
const handleClick = e => {
handleState(e.target.values)
}
return (
<button onClick={handleClick}>Change State</button>
)
}
const Child2 = props => {
const { currentState } = useContext(AppContext)
return (
<h1>{currentState}</h1>
)
}
const Parent = props => {
return (
<Router>
<AppProvider>
<Route component={Child1} />
<Route component={Child2} />
</AppProvider>
</Router>
)
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
我目前正在创建一个搜索栏,其中 App
是 parent,Header
,Home
是 children。我试图通过 App
将输入从 Header
传递到 Home
,但似乎当我尝试加载 {this.state.searchValue}
时它什么也没做。
我不知道我的代码哪里出错了。我还使用 Route
将道具从 Header
路由到 Home
。
这是我的代码:
Header.js (Child 1)
class Header extends Component {
constructor(props) {
super(props);
this.state = {
search: "",
};
}
onChange = (event) => {
this.setState({ search: event.target.value });
};
submitSearch = (event) => {
event.preventDefault();
console.log(this.state.search);
this.props.passSearchData(this.state.search);
};
render() {
return (
<React.Fragment>
<nav className="navbar navbar-expand-lg navbar-light bg-light">
<form className="form-inline">
<input
className="form-control mr-sm-2"
type="text"
placeholder="Search"
onChange={this.onChange}
/>
<button
className="btn btn-danger"
type="submit"
onClick={this.submitSearch}
>
Search
</button>
</form>
</nav>
</React.Fragment>
);
}
}
export default Header;
App.js (Parent)
class App extends Component {
constructor() {
super();
this.state = {
searchValue: "",
};
}
handleSearchData = (search) => {
this.setState({ searchValue: search });
};
componentDidMount() {
this.props.getItems();
}
render() {
return (
<div className="App">
<Router>
<Header passSearchData={this.handleSearchData} />
<Route
exact
path="/"
render={(props) => (
<Home {...props} searchValue={this.state.searchValue} />
)}
/>
</Router>
<Footer />
</div>
);
}
}
Home.js
class Catalog extends Component {
constructor(props) {
super(props);
this.state = {
};
}
render() {
return (
<div>
<p>{this.props.searchValue}</p>
</div>
);
}
}
我认为使用 React 上下文更好地解决这个问题,因为在路由之间传递状态非常痛苦
首先你声明你自己的提供者作为组件之间的中介。
上下文将保存所有应用程序状态。并使用您的组件,只需使用 useContext
并传递您想要使用的上下文,在这个用例中,我称之为 AppContext
。通过使用相同的上下文,您的组件会获得相同的状态并立即触发更新
我提供的解决方案是使用功能组件。如果您正在使用 class 组件,只需简单地创建一个功能组件,然后将上下文传递给 class 组件
import React, { useContext, useState } from 'react'
const AppContext = React.createContext({})
const AppProvider = props => {
const [currentState, setCurrentState] = useState(null)
const handleState = value => {
setCurrentState(value)
}
const contextValue = { handleState, currentState }
return (
<AppContext.Provider value={contextValue}>
{props.children}
</AppContext.Provider>
)
}
const Child1 = props => {
const { handleState } = useContext(AppContext)
const handleClick = e => {
handleState(e.target.values)
}
return (
<button onClick={handleClick}>Change State</button>
)
}
const Child2 = props => {
const { currentState } = useContext(AppContext)
return (
<h1>{currentState}</h1>
)
}
const Parent = props => {
return (
<Router>
<AppProvider>
<Route component={Child1} />
<Route component={Child2} />
</AppProvider>
</Router>
)
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>