需求:
列表可以分别展开自己的内容,互不影响,我选择了手搓……
每一条的展开or关闭状态,与内容展示,存为一个对象,最后合为一个数组,存放在状态里
const [content, setContent] = useState([]);
数据请求拿到数据以后处理一下数据:
const fetchRecord = async () => { setLoading(true); const params = { id: urlQuery.id }; const result = await getOperateRec(params); if (result.code === 10000) { setData(result.data); const newText = result.data.map(item => ({ key: item.operateContent ? 1 : 0, value: '' })); setContent(newText); } else { message.error(result.msg); } setLoading(false); }; useEffect(() => { fetchRecord(); }, []);
// 0代表- 1代表+
dom代码:
<ul> {data && data.map((item, index) => ( <li key={item.id}> <div> <p style={{ marginBottom: '14px', display: 'flex' }}> <span> {index + 1}、{moment(item.operateTime).format('YYYY-MM-DD HH:mm')},由【 {item.operateEmployeeName}】操作【 {item.operateName}】 </span> {item.operateContent && ( <i className={ getPath(content, `${index}.key`) === 1 ? 'icon iconfont iconplus-square' : 'icon iconfont iconminus-square' } style={{ color: '#FF9E00', cursor: 'pointer', marginLeft: '4px', fontSize: '16px' }} onClick={() => { keyChild( item.operateContent, getPath(content, `${index}.key`), index ); }} ></i> )} </p> {getPath(content, `${index}.value`)} </div> </li> ))} </ul>
展开与收回的展示控制的方法:
const keyChild = (text, isOpen, index) => { setContent([ ...content.slice(0, index), { key: isOpen === 1 ? 0 : 1, value: isOpen === 1 ? ( <div dangerouslySetInnerHTML={{ __html: text }} style={{ marginLeft: '1.5em', marginBottom: '20px' }} ></div> ) : ( '' ) }, ...content.slice(index + 1) ]); };
最终效果:
代码review时,姐妹提出了一个优化方案,就是把当前展开状态的index存起来为一个数组来控制状态,点击图标的时候,拿当前idnex遍历一下数组就好了,果然比我的方法简单还更优,有空优化一下代码,共勉