У меня есть два дочерних компонента, обновляющие одно и то же состояние родительского компонента. оба дочерних компонента содержат цикл, и каждый элемент цикла обновляет состояние при щелчке по событию.

Родительский компонент: -

const [selected, setSelected] = useState('')

const selectContact = (e: SyntheticEvent<HTMLDivElement>) => {
    const {id} = e.currentTarget
    setSelected(id)
    console.log(id)
}


<ChannelList selected={selected} setSelected={selectContact}
          ....other props />

<FriendList selected={selected} setSelected={selectContact} ......other props />}

Я не включил весь компонент, очевидно.

Компонент ChannelList: -

{channels.map(channel =>
    <div key={channel.id}>
        <div id={channel.id}
             className={`channel-list ${selected === channel.id && 'selected-channel'}`}
             onClick={(e) => {
                  setSelected(e)
                  channelDetails(channel.id)
             }}

        // .....rest of my code
    <div>
}

Компонент FriendLiest: -

{friends.map(friend =>
     <div key={friend.id} id={friend.id}
          className={`friend-list-item ${selected === friend.id && 'selected-user'}`}
          onClick={(e) => setSelected(e)}>

     //.......the rest
     <div>
}

То, что я пытаюсь сделать, это изменить стиль в соответствии с состоянием. Если я щелкаю по разным элементам в одном и том же компоненте, состояние обновляется, и CSS отображается нормально. Но если я щелкну что-нибудь на другом компоненте, хотя состояние обновлений CSS-стиля остается на обоих компонентах.

это то, что происходит, что я не хочу

То, что я хочу, это стиль должен отображаться только на одном из компонентов. Я использую реагирующие хуки и Typescript.

Другими словами, если я нажимаю на имя друга, выбранный канал должен быть не выбран, и наоборот.

Любая помощь будет очень ценится.

1
Ashik80 20 Июл 2020 в 20:37

2 ответа

Лучший ответ

Вы пытались использовать какую-либо библиотеку управления состояниями, такую как Mobx или Redux, чтобы наблюдать изменения? Я думаю, что использование одного из них должно решить вашу проблему.

1
Ragib Ibne Hossain 20 Июл 2020 в 20:13

У вас конфликт с одинаковыми идентификаторами на обоих компонентах. Есть несколько подходов, которые я мог бы предложить:

Во-первых, вы можете использовать префикс для определения выбранного состояния:

const selectContact = (prefix: String) => (e: SyntheticEvent<HTMLDivElement>) => {
    const {id} = e.currentTarget
    setSelected(`${prefix}_${id}`)
}

<ChannelList selected={selected} setSelected={() => selectContact('channel')}
      ....other props />
<FriendList selected={selected} setSelected={() => selectContact('friend')} ......other props />

В компонентах канала и друга вы также можете проверить префикс:

{channels.map(channel =>
    <div key={channel.id}>
        <div id={channel.id}
             className={`channel-list ${selected === `channel_${channel.id}` && 'selected-channel'}`}
             onClick={(e) => {
                  setSelected(e)
                  channelDetails(channel.id)
             }}

        // .....rest of my code
    <div>
}

Другим способом, вы можете создать другое состояние, чтобы контролировать, какой компонент выбран (который почти совпадает с префиксом):

const [selected, setSelected] = useState('')
const [componentName, setComponentName] = useState('')
const selectContact = (componentName: String) => (e: SyntheticEvent<HTMLDivElement>) => {
    const {id} = e.currentTarget
    setComponentName(componentName)
    setSelected(id)
}
 <ChannelList selected={selected} isComponentSelected={componentName === 'channel'} setSelected={() => selectContact('channel')}
      ....other props />
<FriendList selected={selected} isComponentSelected={componentName === 'friend'} setSelected={() => selectContact('friend')} ......other props />

На канале:

{channels.map(channel =>
    <div key={channel.id}>
        <div id={channel.id}
             className={`channel-list ${isComponentSelected && selected === channel.id && 'selected-channel'}`}
             onClick={(e) => {
                  setSelected(e)
                  channelDetails(channel.id)
             }}

        // .....rest of my code
    <div>
}
0
buzatto 21 Июл 2020 в 05:38