5
\$\begingroup\$

I have a component, it's actually an entire screen in my application. This screen/component renders multiple other components. However, what it renders is conditional. Currently, I have an if statement, which decides which markup is returned. The only differences between the two markups is one additional <PDFPreview> component is added. I'm pretty sure this isn't the best way to go about this...

const SearchScreen = ({navigation}) => {
 const [ makeSelected, setMakeSelected ] = useState(null);
 const [ modelSelected, setModelSelected ] = useState(null);
 const [ yearSelected, setYearSelected ] = useState(null);
 const [ typeSelected, setTypeSelected ] = useState(null);
 const selectMakeHandler = newMakeData => {
 let makeId = newMakeData.id;
 setMakeSelected(makeId);
 }
 const selectModelHandler = newModelData => {
 let modelId = newModelData.id;
 setModelSelected(modelId);
 }
 const selectYearHandler = newYearData => {
 let yearId = newYearData.id;
 setYearSelected(yearId);
 }
 const selectTypeHandler = newTypeData => {
 let typeId = newTypeData.diagramTypeId;
 setTypeSelected(typeId);
 }
 if (typeSelected !== null)
 {
 return (
 <Layout style={styles.mainContainer1}>
 <Layout style={styles.pickerContainer}>
 <MakePicker 
 onSelectMake={selectMakeHandler}
 />
 <ModelPicker 
 onSelectModel={selectModelHandler}
 makeId={makeSelected}
 />
 <YearPicker 
 makeId={makeSelected}
 modelId={modelSelected}
 onSelectYear={selectYearHandler}
 /> 
 <DiagramTypePicker
 makeId={makeSelected}
 modelId={modelSelected}
 modelYearId={yearSelected}
 onSelectType={selectTypeHandler}
 />
 <Layout style={styles.previewContainer}>
 <PdfPreview
 makeId={makeSelected}
 modelId={modelSelected}
 modelYearId={yearSelected}
 typeId={typeSelected}
 />
 </Layout>
 <Layout style={styles.btnContainer}>
 <Button 
 onPress={() => navigation.navigate('Pdf')}
 >
 Download
 </Button>
 </Layout>
 </Layout>
 <Layout style={styles.adContainer}>
 <Advertisement/>
 </Layout>
 </Layout>
 )
 } 
 else 
 {
 return (
 <Layout style={styles.mainContainer2}>
 <Layout style={styles.pickerContainer}>
 <MakePicker 
 onSelectMake={selectMakeHandler}
 />
 <ModelPicker 
 makeId={makeSelected}
 onSelectModel={selectModelHandler}
 />
 <YearPicker 
 makeId={makeSelected}
 modelId={modelSelected}
 onSelectYear={selectYearHandler}
 /> 
 <DiagramTypePicker
 makeId={makeSelected}
 modelId={modelSelected}
 modelYearId={yearSelected}
 onSelectType={selectTypeHandler}
 />
 </Layout>
 <Layout style={styles.adContainer}>
 <Advertisement/>
 </Layout>
 </Layout>
 )
 }
};


When a diagram is selected from the <DiagramTypePicker>, SearchScreen should re-render, every time, only now it should additionally render the PDF preview of the diagram type selected from <DiagramTypePicker>. If no preview is available for the diagram which was selected, I would like SearchScreen to instead show the original markup, the one without the PDF preview. I know with the useState() and useEffect() hooks I can watch the state of 'typeSelected' to control the re-render, but I'm still not sure if a huge 'if' statement with two different markups is the best way to go about this. Oh, and if the preview is unavailable the additional 'download' button would also be removed. Any advice? Comments? Questions or concerns? Thanks!

asked Nov 14, 2019 at 20:47
\$\endgroup\$

1 Answer 1

2
\$\begingroup\$

You can use ternary operator(?:) or logical AND(&&) operator and React Fragment to avoid this big if-else. The if-else with repetitive code violates DRY principle and should be avoided as any update to the code will be required at 2 different places which will be prone to error in case one is missed

const SearchScreen = ({ navigation }) => {
 ...
 return (
 <Layout style={typeSelected !== null ? styles.mainContainer1 : styles.mainContainer2}>
 <Layout style={styles.pickerContainer}>
 <MakePicker
 onSelectMake={selectMakeHandler}
 />
 <ModelPicker
 onSelectModel={selectModelHandler}
 makeId={makeSelected}
 />
 <YearPicker
 makeId={makeSelected}
 modelId={modelSelected}
 onSelectYear={selectYearHandler}
 />
 <DiagramTypePicker
 makeId={makeSelected}
 modelId={modelSelected}
 modelYearId={yearSelected}
 onSelectType={selectTypeHandler}
 />
 {typeSelected !== null &&
 <>
 <Layout style={styles.previewContainer}>
 <PdfPreview
 makeId={makeSelected}
 modelId={modelSelected}
 modelYearId={yearSelected}
 typeId={typeSelected}
 />
 </Layout>
 <Layout style={styles.btnContainer}>
 <Button
 onPress={() => navigation.navigate('Pdf')}
 >
 Download
 </Button>
 </Layout>
 </>
 }
 </Layout>
 <Layout style={styles.adContainer}>
 <Advertisement />
 </Layout>
 </Layout>
 )
};

Ternary Operator can be used as:

{typeSelected !== null
 ? <>
 <Layout style={styles.previewContainer}>
 <PdfPreview
 makeId={makeSelected}
 modelId={modelSelected}
 modelYearId={yearSelected}
 typeId={typeSelected}
 />
 </Layout>
 <Layout style={styles.btnContainer}>
 <Button
 onPress={() => navigation.navigate('Pdf')}
 >
 Download
 </Button>
 </Layout>
 </>
 : null
}

Note:

  • <></> is short for React.Fragment
  • Please try to use logical && in these cases for better readability purposes.

Hope it helps. Revert for any doubts

answered Dec 26, 2019 at 7:34
\$\endgroup\$

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.