React组件点击切换渲染问题:寻求无需拆分按钮组件的优化方案
Hey there! Let's sort out your component's conditional rendering logic—first we'll fix a critical bug, then make the implementation cleaner without needing to split the button area into a separate component.
First: Fix the Critical onClick Bug
Your current onClick handler has a big issue: you're directly calling this.setState({ showComponent: true }) instead of passing a function. This means setState runs immediately when the component renders, not when the button is clicked. That's why your component might be jumping straight to <ComponentToShow /> without any user interaction.
Fix it by wrapping the setState call in an arrow function:
onClick={() => this.setState({ showComponent: true })}
Optimized Conditional Rendering (No Extra Components Needed)
You don't need to extract the button container into a separate component to keep things clean. Here are two straightforward ways to implement this efficiently:
Option 1: Use a Variable to Store Render Content
This keeps your render method's return statement clean by assigning the conditional content to a variable first:
constructor(props) { super(props); this.state = { showComponent: false }; } render() { let content; if (!this.state.showComponent) { content = ( <div className="button_wrapper"> <button className="upload_button" onClick={() => this.setState({ showComponent: true })} > {i18next.t("GENERAL.uploadBill")} </button> <p className="or_txt">{i18next.t("GENERAL.or")}</p> <button className="manual_button"> {i18next.t("GENERAL.fillManually")} </button> </div> ); } else { content = <ComponentToShow />; } return <>{content}</>; }
Option 2: Simplify the Ternary Expression
If you prefer keeping everything in the return statement, you can trim unnecessary fragment wrappers and clean up the JSX:
constructor(props) { super(props); this.state = { showComponent: false }; } render() { return ( <> {!this.state.showComponent ? ( <div className="button_wrapper"> <button className="upload_button" onClick={() => this.setState({ showComponent: true })} > {i18next.t("GENERAL.uploadBill")} </button> <p className="or_txt">{i18next.t("GENERAL.or")}</p> <button className="manual_button"> {i18next.t("GENERAL.fillManually")} </button> </div> ) : ( <ComponentToShow /> )} </> ); }
Key Improvements
- Fixed the
onClickhandler to only triggersetStatewhen the button is clicked - Removed unnecessary empty fragment wrappers (
<>) that were cluttering the JSX - Kept all logic within the main component, avoiding the need for extra component splits
- Made the conditional rendering logic more readable and maintainable
内容的提问来源于stack exchange,提问作者Noble Polygon

