javascript - react : strange behaviour on hover

标签 javascript reactjs

我是 React 新手,正在制作一个小型“推文框”应用程序进行练习。有一些奇怪的事情我不明白......

用户可以将图像添加到推文中。图像作为对象存储在数组中,并通过循环和运行 renderThumb() 方法进行渲染。在图像悬停时,我在图像的右上角显示一个小的“删除图标”。单击后,图像将被删除。

  1. 当我将鼠标悬停在图像上时,所有显示的图像都会悬停(图标在所有图像上可见)。为什么?

  2. renderThumb() 在悬停时执行。为什么? (它应该只在渲染图像时执行)。

  3. 我使用 this.state.images.filter( (img) => { return img.id != image.id; } ); 删除图像。但这不起作用。为什么?

//谢谢, 奥莱

TweetBox.js

import React, {Component, PropTypes} from 'react';
import './tweetbox.css';

import ReactCSSTransitionGroup from 'react-addons-css-transition-group'

import TextArea from './TextArea';

class TweetBox extends Component {

    numPhotoChars = 17;
    numStartChars = 140;
    author = 'Ole Frank Jensen';
    counter = 0;
    imageUrl = 'http://i.imgur.com/Crcz7dJ.jpg';

    constructor(props) {
        super(props);

        this.state = {
            text: '',
            author: this.author,
            date: 0,
            startValue: this.numStartChars,
            images: []
        };

        this.onTextareaChange = this.onTextareaChange.bind(this);
        this.getNumRemainingChars = this.getNumRemainingChars.bind(this);
        this.disableTextarea = this.disableTextarea.bind(this);
        this.addImage = this.addImage.bind(this);
        this.removeImage = this.removeImage.bind(this);
        this.submitTweet = this.submitTweet.bind(this);
        this.onMouseOver = this.onMouseOver.bind(this);
        this.onMouseOut = this.onMouseOut.bind(this);

    }

    onTextareaChange(e) {
        this.setState({text: e.target.value});
    }

    getNumRemainingChars() {
        return this.state.startValue - this.state.text.length;
    }

    disableTextarea() {
        return this.state.text.length > 0 || this.state.images.length;
    }

    addImage() {
        if (this.getNumRemainingChars() >= this.numPhotoChars) {
            const startValue = this.state.startValue - this.numPhotoChars;
            const image = Object.assign({}, {
                id: this.counter += 1,
                url: this.imageUrl
            });

            this.setState({startValue: startValue});
            this.setState({images: [...this.state.images, image]});
        }
    }

    removeImage(image) {

        let arr = this.state.images.filter( function(img) { return img.id != image.id; } );
        console.log(image, arr);

        this.setState({
            images: this.state.images.filter( function(img) { return img.id != image.id; } ),
            startValue: this.state.startValue + this.numPhotoChars,
            hover: false
        });
    }

    submitTweet(e) {
        e.preventDefault();

        // compose
        const tweet = {
            text: this.state.text,
            author: this.state.author,
            date: new Date().getTime(),
            images: this.state.images
        };

        // store
        this.props.storeTweet(tweet);

        // reset
        this.setState({
            text: '',
            images: [],
            startValue: this.numStartChars
        });
    }

    onMouseOver() { console.log('over'); this.setState({hover: true}); }
    onMouseOut() { console.log('out'); this.setState({hover: false}); }

    renderThumb(image, index) {
        console.log(index);
        let k = 'image-' + index;
        return (
            <div key={k} className="col-xs-3">
                <div className="thumbnail-wrapper">
                    <img src={image.url}
                         alt="My something"
                         className="img-thumbnail"
                         onMouseOver={ this.onMouseOver }
                         onMouseOut={ this.onMouseOut }/>
                    <div className={"img-thumbnail-close-btn " + (this.state.hover ? 'show' : 'hidden')}
                         onMouseOver={ this.onMouseOver }
                         onMouseOut={ this.onMouseOut }
                         onClick={ () => { this.removeImage({image}) } }>
                        <span className="fa-stack fa-1x">
                            <i className="fa fa-circle fa-stack-2x white-background"></i>
                            <i className="fa fa-circle-thin fa-stack-2x black-border"></i>
                            <i className="fa fa-times fa-stack-1x"></i>
                        </span>
                    </div>
                </div>
            </div>
        );
    }

    render() {
        return (
            <div className="tweet-box">
                <div className="row">
                    <div className="col-xs-6 col-xs-offset-3">
                        <div className="well tweet-box clearfix">

                            <h1>Tweet Box</h1>

                            <TextArea value={ this.state.text }
                                      maxLength={this.state.startValue}
                                      onChange={this.onTextareaChange}/>
                            <span className="pull-right">
                                <em>{this.getNumRemainingChars()} characters left...</em>
                            </span>

                            <br/>

                            <div className="row">
                                <ReactCSSTransitionGroup transitionName="example"
                                                         transitionEnterTimeout={500}
                                                         transitionLeaveTimeout={500}>
                                    {
                                        this.state.images.map((image, index) => {
                                            return this.renderThumb(image, index);
                                        })
                                    }
                                </ReactCSSTransitionGroup>
                            </div>


                            <br/>

                            <div className="row">
                                <div className="col-xs-6">
                                    <button className="btn btn-default add-photo pull-left"
                                            onClick={this.addImage}>
                                        <i className="fa fa-camera"></i> Add photo
                                    </button>
                                </div>
                                <div className="col-xs-6">
                                    <button onClick={this.submitTweet} className="btn btn-primary pull-right"
                                            disabled={!this.disableTextarea()}>
                                        <i className="fa fa-pencil-square-o"></i> Tweet!
                                    </button>
                                </div>
                            </div>

                        </div>
                    </div>
                </div>
            </div>
        )
    }

}

TweetBox.propTypes = {
    storeTweet: PropTypes.func.isRequired
};

export default TweetBox;

最佳答案

您的状态被设计为通用的,id建议您在每个图像上添加id。并添加一个接受该 id 的处理程序。这样您就可以仅更改特定图像的悬停。

this.setState({hover: true})

您可以在下面看到您正在向所有图像添加相同的处理程序, 因此,悬停一张图像将导致所有图像都悬停。

<img src={image.url}
  alt="My something"
  className="img-thumbnail"
  onMouseOver={ this.onMouseOver }
  onMouseOut={ this.onMouseOut }/>

关于javascript - react : strange behaviour on hover,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42946410/

相关文章:

reactjs - React Router V4 但在 package.json 中的不同主页上...修复 404 未找到?

javascript - querySelectorAll 没有选择合适的元素

javascript - 过渡到页面上的 anchor

reactjs - 在 React 中检索数据属性值的最佳实践

javascript - 有什么方法可以访问 Next.js 中的 `__filename` 吗?

reactjs - react : Trouble implementing Redux with React-router

javascript - 断点不适用于 Button 或 div 元素,但适用于 li 元素

javascript - 将 html 转换为图像,并保存?(使用 html2canvas.js)

javascript - 使用 JavaScript 在对象内添加属性

javascript - 如何在react中自动启动bootstrap模式