Javascript 组件重复、三次、四次单击反应

Javascript 组件重复、三次、四次单击反应,javascript,reactjs,Javascript,Reactjs,我有一个应用程序,允许用户创建频道/聊天室进行交谈 我创建了一些逻辑,这样当用户按下按钮时,他们就会创建一个通道,function:onCreateChannel 此函数将createChannel状态更改为true,然后显示存储在showChannelInput中的代码。这就是我想要的行为,这样用户就可以键入他们频道的名称并为其分配一个类别 当用户第一次填写输入并选择类别时,一切正常,我想要的行为正常。但是,当用户在第二次、第三次和第四次单击“创建频道”按钮时,请尝试showChannelIn

我有一个应用程序,允许用户创建频道/聊天室进行交谈

我创建了一些逻辑,这样当用户按下按钮时,他们就会创建一个通道,function:onCreateChannel

此函数将createChannel状态更改为true,然后显示存储在showChannelInput中的代码。这就是我想要的行为,这样用户就可以键入他们频道的名称并为其分配一个类别

当用户第一次填写输入并选择类别时,一切正常,我想要的行为正常。但是,当用户在第二次、第三次和第四次单击“创建频道”按钮时,请尝试showChannelInput代码重复,每次重复三倍/四倍

我希望每次用户单击“创建频道”按钮时,它每次只显示一次showChannelInput代码。。。。有人知道为什么会这样吗?我说得通吗

代码如下:

export default function Channels() {
  const { currentUser, venue, venueUpdateHandler } = useContext(AuthContext);

[...]
  const channelData = setupChannels(venue !== null ? venue.chatRooms : []); //venue is coming from auth context and has the chatrooms in it as an object key

  const [channelName, setChannelName] = useState('');

  const [channels, setChannels] = useState(channelData);

  const [createChannel, setCreateChannel] = useState(false);

  const onFormControlChange = (event, key) => {
    if (event.target.value.length <= 100) {
      if (channels[key]) {
        let existingChannels = [...channels];
        existingChannels[key].name = event.target.value;
        setChannels(existingChannels);
      } else {
        setChannelName(event.target.value); // add new channel
      }
    }
  };

[...]

  const onAddChannelKeyPress = event => {
    if (event.key === 'Enter') {
      event.preventDefault();
      onAddChannelClick();
    }
  };

  const onCreateChannel = () => {
    setCreateChannel(true);
  };

  const onAddChannelClick  = () => {
    if (channelName === '') {
      return;
    }

    let existingChannels = [...channels];
    let newChannel = {
      key: existingChannels.length,
      name: channelName,
      deletable: true,
      markedForDelete: false,
      category: null
    };
    existingChannels.push(newChannel);
    setChannels(existingChannels);
    setChannelName('');
    setCreateChannel(false);
 };


  [...]




  let displayExistingChannels =  null;
  if (channels !== null){
   displayExistingChannels = (
      channels.map(channel => {
        return (
          <Grid key={channel.key} item style={styles.gridItem} justify="space-between">
            <ChannelListItem
              channel={channel}
              isSaving={isSaving}
              onDeleteChannelClick={onDeleteChannelClick}
              key={channel.key}
              onFormControlChange={onFormControlChange}
              onUndoChannelClick={onUndoChannelClick}
            />
          </Grid>
        )
      })
    )
  }


  let showChannelInput = null;
  if (createChannel) {
    showChannelInput = (
      channels.map(channel => {
        return (
          <Grid key={channel.key} item style={styles.gridItem} justify="space-between">
            <Grid item style={styles.gridItem}>
              <ChannelFormControl
                channelName={channelName}
                isSaving={isSaving}
                onFormControlChange={onFormControlChange}
                onAddChannelClick={onAddChannelClick} 
                onAddChannelKeyPress={onAddChannelKeyPress}
              />
            </Grid>
            <Grid>
              <ChannelCategory
                visible={true}
                onChange={value => onAddCategory(value, channel.key)}
                title="Add your channel to a category so that users can find it with ease"
                selected={channel.category}
                name={channel.key} // unique for every channel
              />
            </Grid>
          </Grid>
        )
      })
    )
  }

  return (
    <form noValidate autoComplete='off' onSubmit={onSubmit}>
      <Card style={styles.card}>
        <ActionResult result={actionResult} onClose={onActionResultClose} />
        <CardContent>
          <Box padding={3}>
            <FormLegend title={`${formTitle} (${channels.length})`} description={formDescription} />

            <Box marginTop={3} width='50%'>
              <Grid container direction='column' justify='flex-start' alignItems='stretch' spacing={1}>
                <ActionButton
                  labelNormal='Create Channel'
                  labelAction='Creating Channel'
                  onClickHandler={onCreateChannel}
                />
                  {displayExistingChannels}
                  {showChannelInput}
                <Grid item>
                  <ActionButton
                    isSaving={isSaving}
                    labelNormal='Save'
                    labelAction='Saving'
                    onClickHandler={onClickSave} 
                  />
                  <Button variant='text' color='secondary' style={styles.resetButton} onClick={onResetClick}>
                    Reset
                  </Button>
                </Grid>
              </Grid>
            </Box>
          </Box>
        </CardContent>
      </Card>
      [...]
    </form>
  );
}

发生这种情况是因为您正在使用channels.map,并且每次触发onAddChannelClick时,它都会将一个新频道推送到多个频道。因此,您应该创建一个新变量,而不是showChannelInput中的channels.map,该变量将从以下通道获取最新的通道:

const newChannel=通道[channels.length-1];
并使用它。或者在没有新变量的情况下,您可以在每个属性中写入此选定={channels[channels.length-1].category}而不是此选定={channel.category}

这是因为您使用的是channels.map,并且每次触发onAddChannelClick时,它都会将新频道推送到频道。因此,您应该创建一个新变量,而不是showChannelInput中的channels.map,该变量将从以下通道获取最新的通道:

const newChannel=通道[channels.length-1];
并使用它。或者在没有新变量的情况下,您可以在每个属性中写入此选定={channels[channels.length-1].category}而不是此选定={channel.category}

代码更改以修复问题

  let showNewChannelInput = null;
  const newChannel = channels[channels.length - 1]; 
  if (createChannel) {
    showNewChannelInput = (
          <Grid key={newChannel.key} item style={styles.gridItem} justify="space-between">
            <Grid item style={styles.gridItem}>
              <ChannelFormControl
                channelName={channelName}
                isSaving={isSaving}
                onFormControlChange={onFormControlChange}
                onAddChannelClick={onAddChannelClick} // adding a new channel input box does this need an attributes prop which is an object
                onAddChannelKeyPress={onAddChannelKeyPress}
              />
            </Grid>
            <Grid>
              <ChannelCategory
                visible={true}
                onChange={value => onAddCategory(value, newChannel.key)}
                title="Add your channel to a category so that users can find it with ease"
                selected={newChannel.category}
                name={newChannel.key} // unique for every channel
              />
            </Grid>
          </Grid>
    )
  }


代码更改以修复问题

  let showNewChannelInput = null;
  const newChannel = channels[channels.length - 1]; 
  if (createChannel) {
    showNewChannelInput = (
          <Grid key={newChannel.key} item style={styles.gridItem} justify="space-between">
            <Grid item style={styles.gridItem}>
              <ChannelFormControl
                channelName={channelName}
                isSaving={isSaving}
                onFormControlChange={onFormControlChange}
                onAddChannelClick={onAddChannelClick} // adding a new channel input box does this need an attributes prop which is an object
                onAddChannelKeyPress={onAddChannelKeyPress}
              />
            </Grid>
            <Grid>
              <ChannelCategory
                visible={true}
                onChange={value => onAddCategory(value, newChannel.key)}
                title="Add your channel to a category so that users can find it with ease"
                selected={newChannel.category}
                name={newChannel.key} // unique for every channel
              />
            </Grid>
          </Grid>
    )
  }