Как по клику одного компонента показать другой компонент React?

вот компонент который хочу показать

import React, {useState} from 'react';
import './List-popup.scss';

const AddList = (onClick) => {
  const [state, setState] = useState(false);
  return state && (<div className="list-popup">
  <h1>123</h1>
</div>)

}

export default AddList;

вот по которому кликнуть для показа, но вылазиет ошибка, TypeError: setState is not a function

import React from 'react';
import './List-button.scss';

const ListButton = ({items,setState}) => {
  return  <button onClick={() => setState(true)} className="todo-header-plus" title="Создать список дел">
{
  items.map((item,index) => (
    <i key={index}>{item.icon}</i>
  ))
}
</button>
}

export default ListButton;

вот само приложение

import React from 'react';
import{ FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import ListTitle from './components/list/List-title';
import ListItem from './components/list-item/List-item';
import ListButton from './components/list-button/List-button';
import AddList from './components/list-popup/List-popup';
import{ faPlusSquare } from '@fortawesome/free-solid-svg-icons';
import{ faClipboardList } from '@fortawesome/free-solid-svg-icons';
import{ faHome } from '@fortawesome/free-solid-svg-icons';
import{ faBriefcase } from '@fortawesome/free-solid-svg-icons';
import{ faPhone } from '@fortawesome/free-solid-svg-icons';
import{ faUtensils } from '@fortawesome/free-solid-svg-icons';
import{ faShoppingCart } from '@fortawesome/free-solid-svg-icons';
import{ faMoneyCheckAlt} from '@fortawesome/free-solid-svg-icons';

function App() {

 return <div className="todo">
    <header className="todo-header">
    <ListButton items={[
      {
        icon: <FontAwesomeIcon icon={faPlusSquare}/>
      }
    ]}
    />
    <input className="todo-header-input" type="text" placeholder="..." maxLength="35"/>
    <button className="todo-header-button">Выход</button>
  </header>
  <main className="todo-content">
    <div className="todo-sidebar">
      <AddList
        onClick={() => setState(true)}
      />
      <ListTitle items={[
        {
          icon: <FontAwesomeIcon icon={faClipboardList}/>,
          name: 'Все задачи'
        }
      ]}
      isRemovable
      />
      <ListItem items={[
        {
          icon: <FontAwesomeIcon icon={faHome}/>,
          name: 'Дом',
          color: 'home'
        },
        {
          icon: <FontAwesomeIcon icon={faBriefcase}/>,
          name: 'Работа',
          color:'work'
        },
        {
          icon: <FontAwesomeIcon icon={faPhone}/>,
          name: 'Звонки',
          color:'phone'
        },
        {
          icon: <FontAwesomeIcon icon={faUtensils}/>,
          name: 'Еда',
          color:'food'
        },
        {
          icon: <FontAwesomeIcon icon={faShoppingCart}/>,
          name: 'Покупки',
          color:'shop'
        },
        {
          icon: <FontAwesomeIcon icon={faMoneyCheckAlt}/>,
          name: 'Финансы',
          color:'money'
        }
      ]}/>
    </div>
    <div className="todo-tasks">

    </div>
  </main>
</div>//end todo
}

export default App;

почему-то кнопка не видит состояние state... подскажите где ошибка


Ответы (3 шт):

Автор решения: santavital
const ListButton = ({items,setState}) => //

В ListButton ты не передал setState

<ListButton items={[
      {
        icon: <FontAwesomeIcon icon={faPlusSquare}/>
      }
    ]}
    />
→ Ссылка
Автор решения: Anvarjon

Вы setState не передаете в ListBUtton

Обьявите state внутри App.jsx и передайте state в AddList, а setState в ListButton

→ Ссылка
Автор решения: ksa

Как по клику одного компонента показать другой компонент React?

Так или иначе - все делается "через общего родителя".

  1. Через реф-ссылку.
  2. Через родительский стейт.
  3. Через родительский стейт + контекст.

const ListButton = ({r}) => {
  const act = _ => r.current(v => !v)
  return <button onClick={act} className="todo-header-plus" title="Создать список дел">
    Реф-ссылка
  </button>
}
const AddList = ({r}) => {
  const [state, setState] = React.useState(false);
  React.useEffect(_ => r.current = setState, [])
  return state && (<div className="list-popup">
    <h1>123</h1>
  </div>)
}
const Button = ({fn}) => {
  const act = _ => fn(v => !v)
  return <button onClick={act}>
    Родительский стейт
  </button>
}
const List = ({on}) => {
  if (!on) return null
  return <div className="list-popup">
    <h1>123</h1>
  </div>
}
const Info = React.createContext({on: false, fn: () => null})
const ButtonCnt = () => {
  const {fn} = React.useContext(Info)
  const act = _ => fn(v => !v)
  return <button onClick={act}>
    Родительский стейт + контекст
  </button>
}
const ListCnt = () => {
  const {ok} = React.useContext(Info)
  if (!ok) return null
  return <div className="list-popup">
    <h1>123</h1>
  </div>
}
//
function App(){
  const [on, setOn] = React.useState(false);
  const [ok, setOk] = React.useState(false);
  const r = React.useRef()
  return <>
    <h1>Вариант 1</h1>
    <ListButton r={r} />
    <AddList r={r} />
    <hr />
    <h1>Вариант 2</h1>
    <Button fn={setOn} />
    <List on={on} />
    <hr />
    <h1>Вариант 3</h1>
    <Info.Provider value={{ok, fn: setOk}}>
      <ButtonCnt />
      <ListCnt />
    </Info.Provider>
  </>
}
const domContainer = document.querySelector('#like_button_container');
const root = ReactDOM.createRoot(domContainer);
root.render(<App />);
<div id="like_button_container"></div>
<script src="https://unpkg.com/react@18/umd/react.development.js"
  crossorigin>
</script>
<script src="https://unpkg.com/react-dom@18/umd/react-dom.development.js" 
  crossorigin>
</script>

→ Ссылка