React TypeScript动态修改轮播组件Section标题求助
问题
使用TypeScript开发时,需要实现:
- 新增帖子时,Section标题显示为“ARTIKEL BARU”或“BERITA BARU”
- 编辑旧帖子时,标题仅显示“ARTIKEL”或“BERITA”
接手现有代码后,尝试删除if else中的“TERBARU”字样但无效果,请教如何实现Section标题的动态修改。
相关代码
表格组件代码
import { useNavigate } from 'react-router'; import { Space, Card, Table, Button, Typography } from 'antd'; import { HomepageProps } from '@customTypes/dashboard'; import { ADD_CAROUSEL, EDIT_CAROUSEL } from '@constants/urls'; const { Title } = Typography; const CarouselCard = ({ data }: { data: HomepageProps[] }) => { const navigate = useNavigate(); const columns = [ { title: 'Section', key: 'otherData', dataIndex: 'otherData', render: (text: { section: string }) => text?.section, }, { title: 'Judul Konten', key: 'title', dataIndex: 'title', }, { title: 'Deskripsi Konten', key: 'content', dataIndex: 'content', }, { title: 'Aksi', key: 'action', render: (_: string, record: any) => ( <Space align="end"> <Button type="link" className="button-link-grey" onClick={() => navigate(EDIT_CAROUSEL + '/' + record.id)} > Ubah </Button> </Space> ), }, ]; return ( <Space direction="vertical" size="middle" style={{ display: 'flex' }}> <Card title={ <Space align="end"> <Title level={4} style={{ marginBottom: 0 }}> Carousel </Title> {data.length < 3 && ( <Button onClick={() => navigate(ADD_CAROUSEL)}> Tambah Baru </Button> )} </Space> } > <Table columns={columns} dataSource={data} pagination={false} /> </Card> </Space> ); }; export default CarouselCard;
编辑页面代码
import { useState, useEffect } from 'react'; import { useLocation, useNavigate } from 'react-router'; import { Card, Row, Col, Space, Button, message, Input, Typography, Select, } from 'antd'; import CustomTitle from '@components/Title'; import { DASHBOARD } from '@constants/urls'; import fetchRequest from '@utils/fetcher'; const { TextArea } = Input; const { Title } = Typography; const { Option } = Select; type TitleProps = { id: string; title: string; type: 'news' | 'article' | 'publication'; }; const EditCarousel = () => { const [id, setId] = useState(''); const [title, setTitle] = useState(''); const [content, setContent] = useState(''); const [articleList, setArticleList] = useState<TitleProps[]>([]); const [newsList, setNewsList] = useState<TitleProps[]>([]); const [publicationList, setPublicationList] = useState<TitleProps[]>([]); const [section, setSection] = useState(''); const navigate = useNavigate(); const location = useLocation(); const handleSubmit = async () => { const titleId = [...articleList, ...newsList, ...publicationList].filter( (al) => al.id === title )[0]; let sec = section; if (section === '') { if (titleId.type === 'news') { sec = 'BERITA TERBARU'; } else if (titleId.type === 'article') { sec = 'ARTIKEL TERBARU'; } else if (titleId.type === 'publication') { sec = 'PUBLIKASI TERBARU'; } } const param = { title: titleId.title, content, section: sec, originId: title, }; try { await fetchRequest({ method: 'POST', path: 'resource/homepage/carousel', data: id !== '' ? { ...param, id } : param, }).then((response) => { if (!response.error) { navigate(DASHBOARD); } else { message.error(response.error.message); } }); } catch (error) { message.error(error.message); } }; const getContent = async (id: string) => { try { await fetchRequest({ method: 'GET', path: 'resource?id=' + id, }).then((response) => { if (!response.error) { setTitle(response.title || ''); setContent(response.content || ''); setSection(response?.otherData?.section || ''); } else { message.error(response.error.message); } }); } catch (error) { message.error(error.message); } }; const getTitleList = async (type: string) => { try { await fetchRequest({ method: 'GET', path: 'info/no-content?types=' + type, }).then((response) => { if (!response.error) { if (type === 'news') { setNewsList(response || []); } else if (type === 'article') { setArticleList(response || []); } else if (type === 'publication') { setPublicationList(response || []); } } else { message.error(response.error.message); } }); } catch (error) { message.error(error.message); } }; const getDataList = async () => { let type = ''; if (section === 'ARTIKEL TERBARU') { type = 'article'; } else if (section === 'PUBLIKASI TERBARU') { type = 'publication'; } else if (section === 'BERITA TERBARU') { type = 'news'; } if (type === '') { getTitleList('news'); getTitleList('publication'); getTitleList('article'); } else { getTitleList(type); } }; useEffect(() => { const isEdit = location.pathname.split('/').filter((pn) => pn === 'edit').length > 0; if (isEdit) { const path = location.pathname.split('/'); const testimonyId = path[path.indexOf('edit') + 1]; setId(testimonyId); getContent(testimonyId); } getDataList(); }, []); return ( <Row> <Col span={12} offset={6}> <Card> <Space direction="vertical" style={{ width: '100%' }}> <CustomTitle name={section || 'Carousel'} url={DASHBOARD} /> <Title level={5}>Pilih judul yang akan ditampilkan</Title> <Select value={title} placeholder="Judul" onChange={(value: any) => setTitle(value)} style={{ width: '100%' }} > {[...articleList, ...newsList, ...publicationList].map((al) => ( <Option key={al.id} value={al.id}> {al.title} </Option> ))} </Select> <Title level={5}>Deskripsi Singkat</Title> <TextArea value={content} onChange={(e: any) => setContent(e.target.value)} rows={4} /> <Row justify="end"> <Col> <Button type="primary" danger onClick={() => handleSubmit()}> Simpan Perubahan </Button> </Col> </Row> </Space> </Card> </Col> </Row> ); }; export default EditCarousel;

解决方案
1. 明确新增/编辑状态
在EditCarousel组件顶部新增判断逻辑,通过id是否为空区分新增和编辑模式:
const isEdit = !!id; // id不为空即为编辑模式
2. 动态调整Section显示文本
新增一个函数处理显示用的Section文本,替换原有CustomTitle的name属性:
const getDisplaySection = () => { if (!section) return 'Carousel'; if (isEdit) { // 编辑模式:移除"TERBARU"后缀 return section.replace(' TERBARU', ''); } else { // 新增模式:将"TERBARU"替换为"BARU" return section.replace(' TERBARU', ' BARU'); } }; // 替换原CustomTitle代码 <CustomTitle name={getDisplaySection()} url={DASHBOARD} />
3. 修正提交时的Section参数
修改handleSubmit中的Section赋值逻辑,确保新增和编辑时提交正确的值:
const handleSubmit = async () => { const titleId = [...articleList, ...newsList, ...publicationList].filter( (al) => al.id === title )[0]; let sec = section; if (section === '') { // 新增模式:直接设置带BARU后缀的Section if (titleId.type === 'news') { sec = 'BERITA BARU'; } else if (titleId.type === 'article') { sec = 'ARTIKEL BARU'; } else if (titleId.type === 'publication') { sec = 'PUBLIKASI BARU'; } } else if (isEdit) { // 编辑模式:移除TERBARU后缀,确保提交的值符合要求 sec = sec.replace(' TERBARU', ''); } // 后续提交逻辑保持不变... };
4. 修复编辑时初始数据的Section处理
在getContent函数中,获取后端数据后直接处理编辑模式的Section:
const getContent = async (id: string) => { try { await fetchRequest({ method: 'GET', path: 'resource?id=' + id, }).then((response) => { if (!response.error) { setTitle(response.title || ''); setContent(response.content || ''); const fetchedSection = response?.otherData?.section || ''; // 编辑模式下提前移除TERBARU后缀 setSection(isEdit ? fetchedSection.replace(' TERBARU', '') : fetchedSection); } else { message.error(response.error.message); } }); } catch (error) { message.error(error.message); } };
5. 兼容Section判断逻辑
修改getDataList中的类型判断,同时兼容带后缀和不带后缀的Section值:
const getDataList = async () => { let type = ''; if (section.includes('ARTIKEL')) { type = 'article'; } else if (section.includes('PUBLIKASI')) { type = 'publication'; } else if (section.includes('BERITA')) { type = 'news'; } if (type === '') { getTitleList('news'); getTitleList('publication'); getTitleList('article'); } else { getTitleList(type); } };
6. 更新useEffect依赖
将isEdit加入useEffect的依赖数组,确保编辑状态变化时能重新获取数据:
useEffect(() => { const editFlag = location.pathname.split('/').filter((pn) => pn === 'edit').length > 0; if (editFlag) { const path = location.pathname.split('/'); const testimonyId = path[path.indexOf('edit') + 1]; setId(testimonyId); getContent(testimonyId); } getDataList(); }, [isEdit]); // 添加isEdit作为依赖
内容的提问来源于stack exchange,提问作者Estherak23
相关产品推荐
相关产品推荐

