React map всегда вызывает метод с данными последнего элемента - PullRequest
0 голосов
/ 11 сентября 2018

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

Я использую интерфейс React Material.

Вот код:

render() {

    const { anchorEl } = this.state;
    const open = Boolean(anchorEl);

    return(
        <Panel>
            <form noValidate autoComplete="off" onSubmit={this.onSubmit}>
                <TextField
                    id={`comment${this.state.post_id}`}
                    name="comment"
                    fullWidth
                    placeholder="Comment here"
                    margin="normal"
                    value={this.state.comment}
                    onChange={this.handleChange}
                    InputProps={{
                        endAdornment : <InputAdornment position="end">
                            <IconButton onClick={this.resetTextField}>
                                <CloseIcon/>
                            </IconButton>
                        </InputAdornment>
                    }}
                />
            </form>

            {this.props.comments && this.props.comments.length > 0 &&
            <RenderComments
                comments={this.state.comments}
                open={open}
                anchorEl={this.state.anchorEl}
                handleClick={this.handleClick}
                handleClose={this.handleClose}
                handleDelete={this.handleDelete}
                handleEdit={this.handleEdit}
            />
            }
        </Panel>
    )
}

const RenderComments = (props) => {
    return props.comments.map(comment =>
        <CommentBase
            key={comment.id}
            comment={comment}
            open={props.open}
            anchorEl={props.anchorEl}
            handleClick={props.handleClick}
            handleClose={props.handleClose}
            handleDelete={props.handleDelete}
            handleEdit={props.handleEdit}
        />
    );
};

    const CommentBase = ({comment, open, anchorEl, handleClick, handleClose, handleDelete, handleEdit}) => (
    <CommentBasePanel>
        <CommentText>
            {comment.text}
            <span style={{ float: 'right', fontSize: 10, color: '#A9A9A9' }}>{moment(comment.created_at).fromNow()}</span>
        </CommentText>
        <HelperAction>
            <MoreVertIcon
                id={comment.id}
                aria-owns={open ? `simple-popper${comment.id}` : null}
                aria-haspopup="true"
                variant="contained"
                onClick={handleClick}
            />
            <Popover
                id={`simple-popper${comment.id}`}
                open={open}
                anchorEl={anchorEl}
                onClose={handleClose}
                anchorOrigin={{
                    vertical: 'bottom',
                    horizontal: 'right',
                }}
                transformOrigin={{
                    vertical: 'top',
                    horizontal: 'right',
                }}
            >
                <Typography style={{ padding: 10, cursor: 'pointer' }} onClick={() => handleEdit(comment)}>
                    Edit
                </Typography>
                <Typography style={{ padding: 10, color: red[500], cursor: 'pointer' }} onClick={() => handleDelete(comment.id)}>
                    Delete
                </Typography>
            </Popover>
        </HelperAction>
    </CommentBasePanel>
);

handleEdit = (comment) => {
    this.setState({ comment: comment.text, comment_id: comment.id })
};

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

enter image description here

Ответы [ 2 ]

0 голосов
/ 11 сентября 2018

Управление Bad Popovers

map копирует одинаковые open и anchorEl реквизиты во все экземпляры Popover - handleClick (вы не показывали это) * открываетвсе они в одном и том же месте ** (последний находится сверху).

ИСПРАВЛЕНИЕ: включает id в handleClick, сохраняет в состоянии и использует в состоянии для open свойство

FIX2: Вы можете использовать один экземпляр <Popover/>, особенно если не отображается какой-либо контент, связанный с конкретным комментарием.

PS.Я провел больше времени, воссоздавая это (угадывая недостающие части) в stackblitz, чем реальную отладку (фактически проверяя только структуру html для <Popover/> с обработанным {comment.id}).В следующий раз покажите более полный код или приведите минимальный рабочий пример.

0 голосов
/ 11 сентября 2018

Если вы обновите метод визуализации RenderComments следующим образом, это должно решить вашу проблему:

const RenderComments = (props) => {
    return props.comments.map(comment =>
        <CommentBase
            key={comment.id}
            comment={comment}
            open={props.open}
            anchorEl={props.anchorEl}
            handleClick={ props.handleClick }
            handleClose={ props.handleClose }
            handleDelete={ () => props.handleDelete(comment.id) }
            handleEdit={ () => props.handleEdit(comment) }
        />
    );
};
...