在React中隐藏和显示文本

时间:2016-11-10 06:32:38

标签: reactjs meteor

嘿,伙计们这是非常愚蠢的事情,但是我在缠着头来解决问题。我试图在我的一个组件中显示/隐藏文本,但我无法做到。我收到I was clicked!消息,所以我知道该函数正在传递。我错过了什么?我是否还需要声明一个visibility css声明,也许这就是我所缺少的。我正在变得富裕起来。 :/

提前致谢:

SnippetList.jsx

import React, { Component, PropTypes } from 'react'
import { createContainer } from 'meteor/react-meteor-data';
import Snippet from './snippet'
import { Snippets } from '../../../api/collections/snippets.js'


class SnippetList extends React.Component {
    constructor(props) {
        super(props);
        this.state = { visible: false }
        this.toggleVisible = this.toggleVisible.bind(this);
    }

    toggleVisible() {
        this.setState( { visible: !this.state.visible } )
        console.log('I was clicked');
    }

    renderSnippets() {

        return this.props.snippets.map( (snippet) => (
            <Snippet 
            key={snippet._id} 
            title={snippet.title}
            content={snippet.content}
            onClick={this.toggleVisible}
            />
        ));
    }

    render() {
        const snippets = Snippets.find({}).fetch({});

        return (
            snippets.length > 0 
            ?
            <ul>{this.renderSnippets()}</ul>
            : 
            <p>No Snippets at this time</p>
        )
    }   
}

SnippetList.propTypes = {
    snippets: PropTypes.array.isRequired,
}

export default createContainer(() => {
    Meteor.subscribe('snippets');

    return {
        snippets: Snippets.find({}).fetch()
    };
}, SnippetList);

Snippet.jsx

import React, { Component, PropTypes } from 'react'

export default class Snippet extends React.Component {

    render() {
        const visible = this.props.toggleVisible
        return (
            <article>
                <header>
                    <h1 className='Snippet-title'>{this.props.title}</h1>
                </header>
                <div className={visible ? 'show' : 'hidden'} onClick={this.props.onClick}>
                    <p className='Snippet-content'>{this.props.content}</p>
                </div>
            </article>
        )
    }
}

Snippet.propTypes = {
    title: PropTypes.string.isRequired,
    content: PropTypes.string.isRequired
    // toggleVisible: PropTypes.func.isRequired
}

1 个答案:

答案 0 :(得分:2)

问题是你没有将隐藏部分作为道具传递。

在Snippet中你做const visible = this.props.toggleVisible但是... toggleVisible没有传递给你的Snippet组件,因此它始终未定义

return this.props.snippets.map( (snippet) => (
    <Snippet 
    key={snippet._id} 
    title={snippet.title}
    content={snippet.content}
    onClick={this.toggleVisible}
    />
));

添加toggleVisible ...也改为此。

return this.props.snippets.map( (snippet) => (
    <Snippet 
        key={snippet._id} 
        title={snippet.title}
        content={snippet.content}
        toggleVisible={this.state.visible}
        onClick={this.toggleVisible}
    />
));

你也应该将你的renderSnippets绑定到类中......意味着将它添加到你的构造函数this.renderSnippets = this.renderSnippets.bind(this);

现在谈谈您的代码,为什么要将<ul>渲染为<article>的父代? ul的孩子应该是<li>我会重构你的组件更像这样。

class SnippetList extends React.Component {
    constructor(props) {
        super(props);
        this.state = { visible: false };
        this.toggleVisible = this.toggleVisible.bind(this);
        this.renderSnippets = this.renderSnippets.bind(this);
    }

    toggleVisible() {
        this.setState( { visible: !this.state.visible } )
        console.log('I was clicked');
    }

    renderSnippets() {
        return this.props.snippets.map( (snippet) => (
            <Snippet 
                key={snippet._id} 
                title={snippet.title}
                content={snippet.content}
                toggleVisible={this.state.visible}
                onClick={this.toggleVisible}
            />
        ));
    }

    render() {
        const snippets = Snippets.find({}).fetch({});
        return (
            snippets.length > 0 
              ?  <ul>{this.renderSnippets()}</ul>
              :  <p>No Snippets at this time</p>
        )
    }   
}


export default class Snippet extends React.Component {
    render() {
        const {toggleVisible: visible} = this.props;
        return (
            <li>
                <article>
                    <header>
                        <h1 className="Snippet-title">{this.props.title}</h1>
                    </header>
                    <div onClick={this.props.onClick}>
                        <p className={visible ? 'show Snippet-content' : 'hidden Snippet-content'}>{this.props.content}</p>
                    </div>
                </article>
            </li>
        )
    }
}