重新渲染条件按钮

问题描述 投票:0回答:1

这是一本互动圣经。

在下面的代码中,我有一些按钮,这些按钮是根据我之前单击的按钮有条件地呈现的。

代码调用 API 来检索数据。

useEffect(() => {
        dispatch(fetchBibleBooks());
        }, [dispatch]);

    useEffect(() => {
        if(selectedBook && chapter){
            dispatch(fetchBibleBookChapter( {selectedBook, chapter} ));
        }
    }, [dispatch, selectedBook, chapter]);

    useEffect(() => {
        setOTBooks(bibleArray.filter(book => book.testament === 'OT'));
    }, [ clickedOT ]);

    useEffect(() => {
        setNTBooks(bibleArray.filter(book => book.testament === 'NT'));        
    }, [ clickedNT ]);  

    useEffect(() => {
        setBookChapters(bibleArray.find(book => book.id === selectedBook)?.chapters || []);
    }, [ selectedBook ]);

    useEffect(() => { 
       bibleArray.filter(chapter => chapter);
       const subsetBibleArray = bibleArray.map( text => text.cleanText ); 
       setChapterText(subsetBibleArray);
       
    });

    return(
        <Container>
            <Row>
                <Col style={{textAlign: 'center'}}>
                    <h1 style={{ color: 'darkblue'}}>Biblia Interactiva</h1>
                    <Button style={{margin: '2rem'}} color='warning' size='lg' onClick={() => setClickedOT(true)}>
                        Antiguo Testamento
                    </Button>{' '}
                    <Button style={{margin: '2rem'}} color='warning' size='lg' onClick={() => setClickedNT(true)}>
                        Nuevo Testamento
                    </Button>
                </Col>
            </Row>
            <Row style={{marginTop:'4rem'}}>
                <Col style={{textAlign:'left', marginLeft:'-18rem'}}>
                    {
                         clickedOT && otBooks.sort((b1, b2) => {
                                    if (b1.order < b2.order) return -1;
                                    if (b1.order > b2.order) return 1;
                                    return 0;
                                }).map(book => (
                                    <Button color='primary' key={book.order} style={{ margin: '4px' }} onClick={() => setSelectedBook(book.id)}>
                                        {book.name}
                                    </Button> 
                            ))
                        }
                </Col>
                <Col style={{textAlign:'left', marginRight:'-18rem'}}>
                    {
                        clickedNT && ntBooks.sort((b1, b2) => {
                                    if (b1.order < b2.order) return -1;
                                    if (b1.order > b2.order) return 1;
                                    return 0;
                                }).map(book => (
                                    <Button color='primary' key={book.order} style={{ margin: '4px' }} onClick={() => setSelectedBook(book.id)}>
                                        {book.name}
                                    </Button>
                            ))}
                </Col>
            </Row>
            <Row>
                <Col style={{textAlign:'center', marginLeft:'', marginTop: '6rem'}}>
                        {
                            bookChapters.map(ch => (
                                    <Button color='success' key={ch.id} style={{ margin: '4px' }} onClick={() => setChapter(ch.chapter)}>
                                        {ch.chapter}
                                    </Button>
                                )
                            )
                        }
                </Col>
            </Row>
            <Row>
                <Col style={{textAlign:'left', marginLeft:'', marginTop: '6rem'}}>
                        {
                            chapterText.map((text, idx) => (
                                    <p key={idx}>
                                        {text}
                                    </p>
                                )
                            )
                        }
                </Col>
            </Row>
        </Container>
    )
}

代码第一次运行良好,但如果我重新单击其中一个圣经书按钮,先前渲染的章节按钮将消失,文本也会消失,这很好,但它应该将章节按钮重新渲染为新的点击相关书籍。

“selectedBook”变量已更新,但状态变量“chapter”仍保留前一章的值,因此新状态具有包含旧章节的新书,并从 API 中获取该章节,并且相关章节按钮不可用没有被渲染。

reactjs api button state conditional-rendering
1个回答
0
投票

有两件事:

  1. 每当“在事件处理程序中”选择一本新书时重置 selectedBookChapter(不在效果中)
const onChangeBook = (id) => {
   setSelectedBook(book.id);
   setSelectedChapter(undefined); // undefined, or null, or similar
}

然后让所有按钮调用此函数

  1. 没有“bookChapters”状态 -
    bookChapters
    是由于选择(或不选择)一本书而计算/导出的,但它不是状态本身。
const bookChapters = bibleArray.find(book => book.id === selectedBook)?.chapters || []

就是这样。它会在每次渲染时重新计算,这很好(除非您遇到性能问题)。您无需状态即可按住

bookChapters

chapterText
不太可能也是状态,它不应该是状态并且效果不应该存在。

看到这个你可能不需要效果

© www.soinside.com 2019 - 2024. All rights reserved.