如何将一个组件中的props onClicked函数传递给另一个组件

时间:2019-01-04 11:17:07

标签: javascript reactjs

我要设置的是,当我在组件Albums.js中单击onClick时,我会得到组件photos.js的内容。具体来说,选择一个相册将使用Photos.js组件从该相册中触发一张照片阵列。

Albums.js

import React from 'react';
import PropTypes from 'prop-types';
import './forAlbum.css'

class Albums extends React.Component {
    constructor(props) {
        super(props);
        this.state = {  
    };
    this.onClicks = this.onClicks.bind(this);
  }
   onClicks = () => {

    console.log("lamus");
   }

  render () {
    const albums = this.props.albums.map((album, i) => {
      return (
        <AlbumThumb name={album.name} img={album.photos[0].src} id={i} key={i}  />
      );
    });
    // console.log(albums);
    console.log(this.onClicks);
    return (
        <div className="thumbContainer">{albums}</div>
    )
  }
}

const AlbumThumb = (props) => (
  <div  className="thumb">
    <div className="thumbImgWrap">
      <img src={require('./GalleryImages/' + props.img)} alt={props.name} />
    </div>
    <h3 className="thumbTitle">{props.name}</h3>
  </div>

);

export default Albums;

这是Photos.js

import React from 'react';
import './forAlbum.css'

const Photos = (props) => {
    const cliced = () => {
        console.log("cliced");
    }
    const photos = props.photos.map(({ photos }) =>
        <div>
            <ul key={photos.id}>
                {photos.id}
            </ul>

            {photos.map((eachThing, i) => {
                return (
                    <PhotoMain name={eachThing.cap} img={eachThing.src} id={i} key={i} />
                );
            })}
        </div>
    );
    // console.log(photos);
    return <div className="thumbContainer" onClick={props.clicked}>{photos}</div>;
};

const PhotoMain = (props) => (
    <div className="thumb" >
        <div className="thumbImgWrap">
            <img src={require('./GalleryImages/' + props.img)} alt={props.name} />
        </div>
        <h3 className="thumbTitle">{props.name}</h3>
    </div>
);

export default Photos;

但是我不怎么联系这个,也许有人有想法或建议?

我尝试在下一个组件GalleryPhotos.js中调用它

<Albums albums={data3} onClick={this.onClicks} />
<Photos photos={data3} />

const data3 = [
    {
    id: '1',
    name: "Siatkówka",
    photos: [
        {
            id: "11",
            src: "siatkowka1.jpg",
            cap: "Siatkówka"
        },
        {
            id: "12",
            src: "siatkowka2.jpg",
            cap: "Siatkówka2"
        },
        {
            id: "13",
            src: "siatkowka3.jpg",
            cap: "Siatkówka3"
        }
        ]
    },
    {
        id: '2',
        name: "Piłka nożna",
        photos:[
            {
                id: "21",
                src: "pilkaNozna1.jpg",
                cap: "Piłka nożna1"
            },
            {
                id: "22",
                src: "pilkaNozna2.jpeg",
                cap: "Piłka nożna2"
            },
            {
                id: "23",
                src: "pilkaNozna3.jpg",
                cap: "Piłka nożna3"
            }
        ]
    }
];

编辑1-过滤方法

const Photos = (props) => {
    const photos = props.photos.filter(photos => photos.id === '1').map(({photos}) => 
        <div>
            <ul key={photos.id}>
            {photos.id} 
            </ul>

            {photos.filter(eachThing => eachThing.id === eachThing.id).map((eachThing, i) =>
            {
            return (
                <PhotoMain name={eachThing.cap} img={eachThing.src} id={i} key={i} />
                    );
            })}
        </div>
    );
    console.log(photos);
    return <div className="thumbContainer">{photos}</div>;
  };

我使用了Filter.js方法,由于有了它,我能够通过识别特定的相册ID(必须显示哪些照片)进行选择,但是我想知道如何相对于组件将其设置为动态。最大的困难是了解如何进行组件之间的连接以使此过滤器有效。另外,我想知道过滤时的组件Albums.js是否具有逻辑性

编辑2: 控制台消息:

Uncaught TypeError: props.photos.filter is not a function
    at Photos (Photos.js:6)
    at mountIndeterminateComponent (react-dom.development.js:14592)
    at beginWork (react-dom.development.js:15082)
    at performUnitOfWork (react-dom.development.js:17903)
    at workLoop (react-dom.development.js:17944)
    at HTMLUnknownElement.callCallback (react-dom.development.js:147)
    at Object.invokeGuardedCallbackDev (react-dom.development.js:196)
    at invokeGuardedCallback (react-dom.development.js:250)
    at replayUnitOfWork (react-dom.development.js:17224)
    at renderRoot (react-dom.development.js:18037)
    at performWorkOnRoot (react-dom.development.js:18919)
    at performWork (react-dom.development.js:18826)
    at performSyncWork (react-dom.development.js:18799)
    at interactiveUpdates$1 (react-dom.development.js:19109)
    at interactiveUpdates (react-dom.development.js:2328)
    at dispatchInteractiveEvent (react-dom.development.js:5134)

The above error occurred in the <Photos> component:
    in Photos (at GalleryPhotosVideos.js:208)
    in div (at GalleryPhotosVideos.js:204)
    in div (at GalleryPhotosVideos.js:196)
    in CSSTransitionGroupChild (created by TransitionGroup)
    in span (created by TransitionGroup)
    in TransitionGroup (created by CSSTransitionGroup)
    in CSSTransitionGroup (at GalleryPhotosVideos.js:190)
    in GalleryPhotosVideos (created by Route)
    in Route (at Content.js:33)
    in Switch (at Content.js:24)
    in div (at Content.js:23)
    in Content (at App.js:14)
    in div (at App.js:12)
    in App (at src/index.js:10)
    in Router (created by BrowserRouter)
    in BrowserRouter (at src/index.js:10)

Uncaught TypeError: props.photos.filter is not a function
    at Photos (Photos.js:6)
    at mountIndeterminateComponent (react-dom.development.js:14592)
    at beginWork (react-dom.development.js:15082)
    at performUnitOfWork (react-dom.development.js:17903)
    at workLoop (react-dom.development.js:17944)
    at renderRoot (react-dom.development.js:18022)
    at performWorkOnRoot (react-dom.development.js:18919)
    at performWork (react-dom.development.js:18826)
    at performSyncWork (react-dom.development.js:18799)
    at interactiveUpdates$1 (react-dom.development.js:19109)
    at interactiveUpdates (react-dom.development.js:2328)
    at dispatchInteractiveEvent (react-dom.development.js:5134)


This message I see when  I click
TypeError: props.photos.filter is not a function
const photos = props.photos.filter(photos => photos.id === photos.id).map(({photos}) => 

2 个答案:

答案 0 :(得分:3)

仅当状态布尔值为true时,包含相册和照片的组件才应呈现“照片”组件。单击您的相册时,此值将更新:

import React, { Component } from 'react'
class ThankYou extends Component {
    constructor(props) {
        super(props)

        this.state = {
            showPhotos: false
        }
    }

    albumClicked = ev => {
        this.setState({ showPhotos: true })
    }

    render() {
        return (
            <>
                <Albums albums={data3} onClick={this.albumClicked} />
                {this.state.showPhotos && <Photos photos={data3} />}
            </>
        )
    }
}

然后调用相册中传递的函数:

const AlbumThumb = (props) => (
    <div className="thumb" onClick={ev => {props.onClick()}}> //Calls the parent function when clicked
        <div className="thumbImgWrap">
            <img src={require('./GalleryImages/' + props.img)} alt={props.name} />
        </div>
        <h3 className="thumbTitle">{props.name}</h3>
    </div>
);

编辑:

我没有注意到AlbumThumb不是您的组件。您必须将函数上移到Album渲染函数(并将其从AlbumThumb中删除):

render() {
    const albums = this.props.albums.map((album, i) => {
        return (
            <div onClick={ev => { props.onClick() }}>
                <AlbumThumb name={album.name} img={album.photos[0].src} id={i} key={i} />
            </div>
        );
    });
    // console.log(albums);
    console.log(this.onClicks);
    return (
        <div className="thumbContainer">{albums}</div>
    )
}

编辑2:

按所有者名称过滤相册:

this.props.albums.filter(album => album.name.includes(myFilterString)).map(...

编辑3:

您的家长班级必须知道被选中的专辑,您必须使用onClick函数将专辑数据发送回给它:

const albums = this.props.albums.map((album, i) => {
    return (
        <div onClick={props.onClick(album)}>
            <AlbumThumb name={album.name} img={album.photos[0].src} id={i} key={i} />
        </div>
    );
});

然后您可以调整您的父班级以存储整个选定的相册,并根据相册显示照片:

class ThankYou extends Component {
    constructor(props) {
        super(props)

        this.state = {
            selectedAlbum: null
        }
    }

    albumClicked = selectedAlbum => ev => {
        this.setState({ selectedAlbum })
    }

    render() {
        const { selectedAlbum } = this.state
        return (
            <>
                <Albums albums={data3} onClick={this.albumClicked} />
                {selectedAlbum && <Photos photos={data3.find(album => album.name === selectedAlbum.name)} />}
            </>
        )
    }
}

答案 1 :(得分:0)

将数据作为状态管理在外部组件中作为状态。并将其作为道具传递给AlbumPhotos。更新相册组件中的照片。

class Outer extends Component {
    constructor(props) {
        super(props)

        this.state = {
            photos: [],
            albums: [
                {
                id: '1',
                name: "Siatkówka",
                photos: [
                    {
                        id: "11",
                        src: "siatkowka1.jpg",
                        cap: "Siatkówka"
                    },
                    {
                        id: "12",
                        src: "siatkowka2.jpg",
                        cap: "Siatkówka2"
                    },
                    {
                        id: "13",
                        src: "siatkowka3.jpg",
                        cap: "Siatkówka3"
                    }
                    ]
                },
                {
                    id: '2',
                    name: "Piłka nożna",
                    photos:[
                        {
                            id: "21",
                            src: "pilkaNozna1.jpg",
                            cap: "Piłka nożna1"
                        },
                        {
                            id: "22",
                            src: "pilkaNozna2.jpeg",
                            cap: "Piłka nożna2"
                        },
                        {
                            id: "23",
                            src: "pilkaNozna3.jpg",
                            cap: "Piłka nożna3"
                        }
                    ]
                }
            ]
        }
    }

    const updatePhotos = (albumId) => {
        // pass this function to album as prop and bind with each album. 
        const album = this.state.albums.filter((album) => album.id === albumId)
        this.setState({
            photos: album.photos
        })
    }
    render() {
        <>
            <Albums albums={this.state.albums} clickHandler={this.updatePhotos} />
            {this.state.photos ? <Photos photos={this.state.photos} /> : null}
        </>
    }
}

Albums中,调用具有相册ID的clickHandler

<AlbumThumb name={album.name}
            img={album.photos[0].src} 
            id={i} 
            key={i}
            onClick={() => this.props.clickHandler(album.id)}  />