我编写了一个demo在父组件中进行保持数据,然后在子组件中进行显示,我暑假保存成功了但是点击不同的列表项,显示的数据都是一样的好像没有更新,没有销毁,也没有重新加载,使用了钩子函数也不行。
父组件保持数据的方法
import { Avatar, List,Collapse } from 'antd';
import React, { useState } from 'react';
import { PlusCircleOutlined,SolutionOutlined,DeleteOutlined } from '@ant-design/icons';
import SolutionComponets from './SolutionComponets';
const handleSave = (formData) => {
const newAttributeData = { ...AttributeData, ...formData };
// 将新数据与旧数据合并,不替换旧数据
setAttributeData({...newAttributeData});
const newNode = {
title: (
<span>
{`${formData.newNodeName}`}
<DeleteOutlined onClick={(event) => handleDelete(`${formData.newNodeNo}-${formData.newNodeName}`, event)} />
</span>
),
value: `${formData.newNodeNo}-${formData.newNodeName}`, // 使用相同格式作为 value
children: [
{ title: `${formData.ProjecTtype}-${formData.Parentlevel} `, value: `${randomId}-1` },
{ title: <PlusCircleOutlined onClick={showModalForm} />, value: `${formData.newNodeNo}-${formData.newNodeName}-2`, children: [] }
]
};
setListData([...listData, newNode]); // 将新节点对象附加到现有列表数据中
setSelectedNode(newNode); // 将新节点设置为当前所选节点
};
子组件引用
return(
<div>
<SolutionComponets
visible={isModalOpenBaic} AttributeData={AttributeData}
onClose={handleCloseModalBasic}
/>
<List style={{width:'50%'}}
itemLayout="horizontal"
dataSource={listData}
renderItem={(item, index) => (
<Collapse bordered>
<Panel header={item.title} key={index}>
<List.Item.Meta
avatar={<Avatar src={`https://xsgames.co/randomusers/avatar.php?g=pixel&key=${index}`} />}
description="This is a solution project for generating Word documents"
/>
<PlusCircleOutlined onClick={showModalForm} style={{ marginLeft: '20px', marginRight: '10px' }} />
<SolutionOutlined onClick={showModalBaisc} />
</Panel>
</Collapse>
)}
/>
</div>
);
子组件
import { Drawer } from 'antd';
import React, { useState, useEffect } from 'react';
function SolutionComponents({ visible, onClose, AttributeData }) {
const handleCloseDrawer = () => {
onClose();
};
return (
<>
<Drawer title="窗体属性" visible={visible} placement="right" onClose={handleCloseDrawer}>
<p>{AttributeData ? AttributeData.newNodeNo : ''}</p>
<p>{AttributeData ? AttributeData.newNodeName : ''}</p>
<p>{AttributeData ? AttributeData.ProjecTtype : ''}</p>
<p>{AttributeData ? AttributeData.Parentlevel : ''}</p>
</Drawer>
</>
);
}
export default SolutionComponents;
我要实现点击不同列表展示不同列表数据
如果React父组件保存数据,子组件展示数据时出现重复显示的情况,可能是因为子组件未正确使用props接收和展示数据,或者在子组件中对数据进行了错误处理。以下是一些可能导致这个问题的原因和解决方法:
在父组件中,需要确保将数据作为props传递给子组件,并且在子组件中正确地声明和使用这些props。例如,如果要将名称为data
的数据传递给子组件,在父组件中应该像这样传递它:
<MyComponent data={myData} />
在子组件中,可以通过props
属性来访问这些数据:
function MyComponent(props) {
return <div>{props.data}</div>;
}
如果子组件在渲染数据时发生了错误,可能会导致数据重复显示。例如,如果正在使用数组中的数据来渲染列表项,则可能需要确保在循环期间使用唯一的key
属性。否则,React将无法确定哪些元素已被添加、更改或删除,并会重新渲染整个列表。例如:
function MyListComponent(props) {
return (
<ul>
{props.data.map((item, index) => (
<li key={index}>{item}</li>
))}
</ul>
);
}
如果数据重复显示,可能是因为数据重复保存在父组件中。在这种情况下,需要确定何时和如何存储数据,并确保只有一个版本的数据可供使用。例如,如果正在从API或其他源动态加载数据,则可能需要将数据存储在Redux store或使用React Hooks来管理它们。
不知道你这个问题是否已经解决, 如果还没有解决的话:我们看看类组件中的 showMessage
方法中,这个类方法从 this.props.user
中读取数据。在 React
中 Props
是不可变(immutable
)的,所以他们永远不会改变。然而,this
是,而且永远是,可变(mutable
)的。事实上,这就是类组件 this 存在的意义。React本身会随着时间的推移而改变,以便你可以在渲染方法以及生命周期方法中得到最新的实例。
所以如果在请求已经发出的情况下我们的组件进行了重新渲染,this.props
将会改变。showMessage
方法从一个“过于新”的 props
中得到了user
。
这暴露了一个关于用户界面性质的一个有趣观察。如果我们说UI在概念上是当前应用状态的一个函数,那么事件处理程序则是渲染结果的一部分 —— 就像视觉输出一样。我们的事件处理程序“属于”一个拥有特定 props
和 state
的特定渲染。然而,调用一个回调函数读取 this.props
的 timeout
会打断这种关联。我们的 showMessage
回调并没有与任何一个特定的渲染“绑定”在一起,所以它“失去”了正确的 props
。从 this
中读取数据的这种行为,切断了这种联系。
解决方案:
在React父组件中保存数据并在子组件中进行更新显示的方法有很多,可以根据具体情况选择使用哪种方法。以下是几种解决方法:
1.使用状态提升
状态提升是React中最基本的解决方案,其原理是将子组件需要使用到的数据从子组件中抽离出来,放到父组件中进行管理。这样子组件就可以通过props来访问这些数据,且当这些数据发生变化时,子组件也能够及时更新。 具体实现步骤如下:
1)在父组件中定义状态,并将其作为props传递给子组件
class Parent extends React.Component {
state = {
data: 'Hello World'
}
render() {
return <Child data={this.state.data} />
}
}
function Child(props) {
return <div>{props.data}</div>
}
2)在父组件中定义修改状态的方法,并将其作为props传递给子组件
class Parent extends React.Component {
state = {
data: 'Hello World'
}
updateData = (newValue) => {
this.setState({ data: newValue })
}
render() {
return <Child data={this.state.data} updateData={this.updateData} />
}
}
function Child(props) {
const handleClick = () => {
props.updateData('Hello React')
}
return (
<div>
<div>{props.data}</div>
<button onClick={handleClick}>Update Data</button>
</div>
)
}
2.使用Context
如果在父组件和子组件之间需要传递多层数据或者需要跨越多个层级进行数据传递,可以考虑使用React的Context。 具体实现步骤如下:
1)在父组件中定义Context
const DataContext = React.createContext()
class Parent extends React.Component {
render() {
return (
<DataContext.Provider value={{ data: 'Hello World' }}>
<Child />
</DataContext.Provider>
)
}
}
2)在子组件中使用Context
function Child(props) {
return (
<DataContext.Consumer>
{context => <div>{context.data}</div>}
</DataContext.Consumer>
)
}
3.使用Redux
如果在整个应用中需要跨越多个组件进行数据传递,可以考虑使用Redux。 具体实现步骤如下:
1)定义数据的初始状态和修改状态的action以及reducer
const initialState = {
data: 'Hello World'
}
export const setDataAction = (newData) => ({
type: 'SET_DATA',
payload: newData
})
export const dataReducer = (state = initialState, action) => {
switch(action.type) {
case 'SET_DATA':
return { ...state, data: action.payload }
default:
return state
}
}
2)创建store,并将其作为props传递给根组件
import { createStore } from 'redux'
import { Provider } from 'react-redux'
import { dataReducer } from './reducers'
const store = createStore(dataReducer)
ReactDOM.render(
<Provider store={store}>
<App />
</Provider>,
document.getElementById('root')
)
3)在子组件中使用数据以及修改数据
import { connect } from 'react-redux'
import { setDataAction } from './actions'
function Child(props) {
const handleClick = () => {
props.setData('Hello React')
}
return (
<div>
<div>{props.data}</div>
<button onClick={handleClick}>Update Data</button>
</div>
)
}
const mapStateToProps = state => ({
data: state.data
})
const mapDispatchToProps = dispatch => ({
setData: (newData) => dispatch(setDataAction(newData))
})
export default connect(mapStateToProps, mapDispatchToProps)(Child)
总结:
以上三种方法都可以实现在React父组件中保存数据并在子组件中进行更新显示的需求,具体使用哪种方法可以根据具体情况进行选择。如果需要进行复杂的状态管理,可以考虑使用Redux;如果仅仅是需要在父子组件之间进行数据传递,可以使用状态提升或者Context。