Home > Net >  Use conditional rendering in React but a variable storing the element is not defined?
Use conditional rendering in React but a variable storing the element is not defined?

Time:04-19

I have a small forum that conditionally renders some buttons, but I could not get it to work since a variable is always 'undefined'

function NewExpense(props) {
  const [isEditing, setIsEditing] = useState(false);

  const startEditingHandler = () => {
    setIsEditing(true);
  };
  
  const saveExpenseDataHandler = (enteredExpenseData) => {
    const expenseData = {
      ...enteredExpenseData,
      id: Math.random().toString(),
    };
    
    props.onAddExpense(expenseData);

//showedElement is not defined in the return statement??
    let showedElement = isEditing ? (
      <ExpenseForm onSaveExpenseData={saveExpenseDataHandler}></ExpenseForm>
    ) : (
      <button onClick={startEditingHandler}>Add New Expense</button>
    );
  };

  return (
    <div className="new-expense">
   //showedElement is not defined
      {showedElement}
    </div>
  );
}

What did I do wrong? I made a variable and conditionally set its value to the rendered element, but React kept yelling at me that it was not defined

CodePudding user response:

Why do you define a local scope variable showedElement in saveExpenseDataHandler?

Because its scope is local (local inside function), it's always undefined.

It's enough to add it in return function.

Check the following code.


function NewExpense(props) {
  const [isEditing, setIsEditing] = useState(false);

  const startEditingHandler = () => {
    setIsEditing(true);
  };

  const saveExpenseDataHandler = (enteredExpenseData) => {
    const expenseData = {
      ...enteredExpenseData,
      id: Math.random().toString(),
    };

    props.onAddExpense(expenseData);
  };

  return (
    <div className="new-expense">
      {isEditing ? (
        <ExpenseForm onSaveExpenseData={saveExpenseDataHandler}></ExpenseForm>
      ) : (
        <button onClick={startEditingHandler}>Add New Expense</button>
      )}
    </div>
  );
}

CodePudding user response:

Another alternative, if you don't want to include this condition explicitly in the component return, you could define a method like this.

function NewExpense(props) {
  const [isEditing, setIsEditing] = useState(false);

  const startEditingHandler = () => {
    setIsEditing(true);
  };
  
  const saveExpenseDataHandler = (enteredExpenseData) => {
    const expenseData = {
      ...enteredExpenseData,
      id: Math.random().toString(),
    };
    
    props.onAddExpense(expenseData);

    const showedElement = () => {
      if (isEditing) {
        return <ExpenseForm onSaveExpenseData={saveExpenseDataHandler}></ExpenseForm>;
      }
      return <button onClick={startEditingHandler}>Add New Expense</button>;
  };

  return (
    <div className="new-expense">
      {showedElement()}
    </div>
  );
}
  • Related