我的React应用程序包含三个组件。其中两个是子组件,另一个是父组件。我需要通过父组件将数据(projectId)从一个子组件传递给另一个子组件,并在接收到数据后触发一个函数。作为示例,我将ProjectId从ChildOne发送到Parent,然后将projectId从ParentOne发送到ChildTwo。 ChildTwo有一个名为setProject(projectId)的函数,一旦收到projectID,我就需要将其触发。 问题是我无法通过单击ChildOne中的按钮来在ChildTwo中触发功能getProjectId。我还尝试了不适合我的componentDidMount和componentWillReceiveProps。我该怎么做?
这是我尝试过的
ChildOne:
class ChildOne extends React.Component {
constructor(props) {
super(props);
this.state = {
projectId: 3,
};
}
sendProjectId = (projectId) => {
this.props.sendId(projectId)
}
render() {
return(
<button onClick={() => this.sendProjectId(this.state.projectId)}>
Click
</button>
)
}
}
父母:
class Parent extends React.Component {
constructor(props) {
super(props);
this.state = {
projectId: '',
};
}
getId = (proId) => {
this.setState({
projectId : proId
})
}
render() {
return(
<div>
<CildOne sendId={this.getId} />
<CildTwo sendOneId={this.state.projectId} />
</div>
)
}
}
ChildTwo:
class ChildTwo extends React.Component {
constructor(props) {
super(props);
this.state = {
projectId: '',
};
}
getProjectId = (this.props.sendOneId) => {
//Do something with this.props.sendOneId
}
render() {
return(
<div></div>
)
}
}
答案 0 :(得分:3)
这将取决于ChildTwo
要用所述数据完成什么。
案例1:
ChildTwo
打算通过相应的projectId
获取一些数据并将其显示在组件中。然后,您可以轻松地在父组件中获取此数据,并将数据作为props
向下传递。
class Parent extends React.Component {
constructor(props) {
super(props);
this.state = {
projectId: '',
dataForChildTwo: null,
};
}
getId = (proId) => {
this.setState({
projectId : proId,
dataForChildTwo: fetchData(proId)
})
}
render() {
return(
<div>
<CildOne sendId={this.getId} />
<CildTwo data={this.state.dataForChildTwo} />
</div>
)
}
}
案例2:
ChildTwo
打算在projectId
更改时对其内部的内容进行一些更改。然后,您可以使用componentDidUpdate
挂钩来查看prop是否已更改并做出响应。
class ChildTwo extends React.Component {
constructor(props) {
super(props);
this.state = {
projectId: '',
};
}
getProjectId = (this.props.sendOneId) => {
//Do something with this.props.sendOneId
}
componentDidUpdate(prevProps) {
if(this.props.projectId!==prevProps.projectId) {
// do something
}
}
render() {
return(
<div></div>
)
}
}
案例3 :
如果以上任何一种情况都不适合您,那么当projectId
使用key
属性更改时,您可以手动重新加载整个组件:
<CildTwo key={this.state.projectId} sendOneId={this.state.projectId} />
注意:这会不必要地重新加载整个组件。
答案 1 :(得分:1)
如果您想设置某些状态,我们可以尝试功能组件或挂钩
function ChildOne(props) {
const [projectId, setProjectId] = useState(3);
function sendProjectId(data){
props.sendId(projectId)
}
return(
<button onClick={() => sendProjectId(projectId)}>
Click
</button>
)
}
function ChildTwo(props) {
const [state, setState] = useState('')
function getProjectId(data) {
//Do something with this.props.sendOneId
console.log(`data here ${data}`)
return false;
}
getProjectId(props.sendOneId)
return (
<div>
</div>
)
}
function Parent(){
const [projectId, setProjectId] = useState('');
function getId(proId) {
setProjectId(proId)
}
return(
<div>
<ChildOne sendId={getId} />
<ChildTwo sendOneId={projectId} />
</div>
)
}
答案 2 :(得分:1)
您在getProjectId
组件的ChildTwo
函数中犯了一个错误。
您的函数无法从prop接收任何内容作为参数。
因此,您的函数应如下所示:
getProjectId = (sendOneId) => {
//Do something with this.props.sendOneId
}
然后您应该像这样使用componentWillReceiveProps
:
componentWillReceiveProps(nextProps) {
if (this.props.sendOneId !== nextProps.sendOneId) {
this.getProjectId(nextProps.sendOneId);
}
}
这是我为解决您的问题而创建的工作代码和框示例: https://codesandbox.io/s/5v4rn7qnll
答案 3 :(得分:1)
您可能应该使用componentDidUpdate
并附带条件,以检查state
更改时是否需要更新sendOneId
中的projectId。然后,您可以使用setState
的回调函数来调用getProjectId
:
componentDidUpdate() {
const { projectId: currentProjectId } = this.state;
const { sendOneId: projectId } = this.props;
if (projectId !== currentProjectId) {
this.setState({ projectId }, () => this.getProjectId());
}
}
完整的示例:
class ChildOne extends React.Component {
constructor(props) {
super(props);
this.state = {
projectId: 3,
};
}
sendProjectId = (projectId) => {
this.props.sendId(projectId)
}
render() {
return (
<button onClick={() => this.sendProjectId(this.state.projectId)}>
Click
</button>
);
}
}
class Parent extends React.Component {
constructor(props) {
super(props);
this.state = {
projectId: '',
};
}
getId = (projectId) => {
this.setState({ projectId });
}
render() {
return (
<div>
<ChildOne sendId={this.getId} />
<ChildTwo sendOneId={this.state.projectId} />
</div>
)
}
}
class ChildTwo extends React.Component {
constructor(props) {
super(props);
this.state = {
projectId: '',
};
}
componentDidUpdate() {
const { projectId: currentProjectId } = this.state;
const { sendOneId: projectId } = this.props;
if (projectId !== currentProjectId) {
this.setState({ projectId }, () => this.getProjectId());
}
}
getProjectId = () => {
console.log(this.state.projectId);
}
render() {
return (
<div></div>
);
}
}
ReactDOM.render(
<Parent />,
document.getElementById('container')
);
<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>
<div id="container"></div>