0

parent component:

    import React from 'react';
    import './Api.scss';
    import ProfileCard from 'components/Card/ProfileCard.jsx';
    import Modal from 'react-awesome-modal';
    // import Search from 'components/Search/Search';

    class Api extends React.Component {
        constructor(props) {
            super(props);
            this.state = {
                title : '',
                content: '',
                img: '',
                data: [],
                pages: 0,
                page:0

            }
        }

        OnFileChange = (event) => {
            this.setState({img: event.target.files[0]});
        }

        onTitleChange = (event) => {
            this.setState({title: event.target.value})
        }

        onContentChange = (event) => {
            this.setState({content: event.target.value})
        }

        resetForm = () => {
            document.getElementById('title').value = '';
            document.getElementById('content').value = '';
            document.getElementById('img').value = '';
        }

        openModal() {
            this.setState({
                visible : true
            });
        }

        closeModal() {
            this.setState({
                visible : false
            });
        } 


        componentDidMount() {
            fetch(`http://127.0.0.1:8000/get_profile/?page=${this.state.page}`)
              .then(response => response.json())
              .then(res =>{
                this.setState({ data: res });  
                this.setState({ pages: res[res.length-1].pages });
                console.log(this.state.page)   
            });
          }


        SubmitProfile = (event) => {
            let formData = new FormData();
            formData.append('img',this.state.img);
            formData.append('title',this.state.title);
            formData.append('content',this.state.content);
            fetch('http://127.0.0.1:8000/post_profile/', {
                method: 'post',
                headers: {
                    Accept: 'application/json, text/plain, */*'
                  },
                  body:formData,
              })
              .then(response => response.json())
              .then(res => {
                  if (res.code === 200){
                    this.componentDidMount()
                    this.resetForm()
                    this.closeModal()
                  }
                  console.log(res);
              })
        }


        elasticSearch = (event) => {
            fetch('http://127.0.0.1:8000/search/', {
                method: 'post',
                headers:{'Content-Type': 'application/json'},
                body: JSON.stringify({
                    q: event.target.value 
                })
        })
        .then(response => response.json())
        .then(res => {
            console.log(res)
            this.setState({ data: res })
        });  
        }





        render(){
            return (
                <div className="api-body">
                    <section>
                        <div className="tc pa2">
                            <input
                                type="button"
                                className="br2 center ph3 pv2 input-reset ba b--black bg-transparent grow pointer f6 dib"
                                value="Post"
                                onClick={() => this.openModal()} 
                            />
                            <input
                                className="db ma3 q center border-box hover-black w-100 measure ba b--black-20 pa2 br2 mb2"
                                type="text"
                                name="q"
                                id="q"
                                onChange = {this.elasticSearch}
                            />
                            </div>
                            <Modal 
                                visible={this.state.visible}
                                width="400"
                                height="300"
                                effect="fadeInDown"
                                onClickAway={() => this.closeModal()}
                            >
                            <div className="mv3 pa3">

                            <label className="db fw6 lh-copy f6" htmlFor="password">Title</label>
                            <input
                                className="db border-box hover-black w-100 measure ba b--black-20 pa2 br2 mb2"
                                type="text"
                                name="title"
                                id="title"
                                onChange={this.onTitleChange}
                            />
                        </div>
                        <div className="mv3 pa3 mt-1">
                            <label htmlFor="comment" className="f6 b db mb2">Contents </label>
                            <textarea 
                                id="content" 
                                name="content" 
                                className="db border-box hover-black w-100 measure ba b--black-20 pa2 br2 mb2" 
                                aria-describedby="content-desc"
                                onChange={this.onContentChange}>
                            </textarea>
                        </div>
                        <div className="mv3 pa3 mt-1">
                        <input
                            type="file"
                            multiple = {false}
                            id="img"
                            name="img"
                            ref={(input) => { this.inpuElement = input; }}
                            accept=".jpg,.jpeg,.png,.pdf,.doc"
                            onChange={this.OnFileChange}
                            />
                        <input
                            type="button"
                            className="br2 center ph3 pv2 input-reset ba b--black bg-transparent grow pointer f6 dib"
                            value="Submit"
                            onClick={this.SubmitProfile} 
                            />
                        </div>
                        </Modal>
                    </section>

                   <ProfileCard 
                    data={this.state.data}
                    pages={this.state.pages}
                    page={this.state.page}
                    />
                </div>
            )
        }
    }


    export default Api;

child component:

    import React from 'react';


    class ProfileCard extends React.Component {
      constructor(props){
        super(props)
        this.state = {
          data : []
        }
      }

      deleteProfile = id => e => {
        fetch('http://127.0.0.1:8000/delete_profile/', {
          method: 'post',
          headers:{'Content-Type': 'application/json'},
          body: JSON.stringify({
            id: id
          })
        })
        .then(response => response.json())
        .then(res => {
            if (res.code === 200){
              this.componentDidMount()
            }
            console.log(res)
        })
      } 

      demoMethod(page){
        this.props.page(page)
        console.log(page)
      }

      render(){
      return (
        <div>
          {
          this.props.data.map((user,i) => {
            return (
              <article className='mw5 tc bg-white dib br3 pa3 ma3 pa4-ns mv3 ba b--black-10 shadow-5 pc-scroll pointer' key={i}>
              <div className="tc">

               <img 
                  src={"http://127.0.0.1:8000" + user.photo}
                  className="br-100 h3 w3 dib" 
                  alt="profile pic"
                  onDoubleClick = {this.deleteProfile(user.id)}
              />
                 <h1 className="f4">{user.title}</h1>
                 <hr className="mw3 bb bw1 b--black-10" />
               </div>
               <p className="lh-copy measure center f6 black-70">
               {user.content}
               </p>
             </article>
            );
          })
        }

          <div className="pagination">
            <center>
                {[...Array(this.props.pages+1)].map((x, i) =>
                  <h2 key={i} onClick={()=>this.demoMethod(i+1)} className="tc">{ i+1 }</h2>
                )}
            </center>
          </div>

        </div>
      );
      }
    }


    export default ProfileCard;

I wants to send data from child to parent component. in child component i have one demoMethod() from that method i wants to send page data to parent component constructor(state).

This way it is not working. And showing this.props.page(page) is not a function

Please have a look into this.

2

4 Answers 4

1

page in parent is not a function but a number variable defined in constructor state so define a new method in Api component and pass down the method to ProfileCard component as prop and in ProfileCard component demoMethod call this.props.getPage(page);

This is so called callbacks in react. To get child data in parent component a function is the only callback that sends data from child to parent

Parent component

import React from 'react';
import './Api.scss';
import ProfileCard from 'components/Card/ProfileCard.jsx';
import Modal from 'react-awesome-modal';
// import Search from 'components/Search/Search';

class Api extends React.Component {
    constructor(props) {
        super(props);
        this.state = {
            title : '',
            content: '',
            img: '',
            data: [],
            pages: 0,
            page:0

        }
    }

    OnFileChange = (event) => {
        this.setState({img: event.target.files[0]});
    }

    onTitleChange = (event) => {
        this.setState({title: event.target.value})
    }

    onContentChange = (event) => {
        this.setState({content: event.target.value})
    }

    resetForm = () => {
        document.getElementById('title').value = '';
        document.getElementById('content').value = '';
        document.getElementById('img').value = '';
    }

    openModal() {
        this.setState({
            visible : true
        });
    }

    closeModal() {
        this.setState({
            visible : false
        });
    } 


    componentDidMount() {
        fetch(`http://127.0.0.1:8000/get_profile/?page=${this.state.page}`)
          .then(response => response.json())
          .then(res =>{
            this.setState({ data: res });  
            this.setState({ pages: res[res.length-1].pages });
            console.log(this.state.page)   
        });
      }


    SubmitProfile = (event) => {
        let formData = new FormData();
        formData.append('img',this.state.img);
        formData.append('title',this.state.title);
        formData.append('content',this.state.content);
        fetch('http://127.0.0.1:8000/post_profile/', {
            method: 'post',
            headers: {
                Accept: 'application/json, text/plain, */*'
              },
              body:formData,
          })
          .then(response => response.json())
          .then(res => {
              if (res.code === 200){
                this.componentDidMount()
                this.resetForm()
                this.closeModal()
              }
              console.log(res);
          })
    }


    elasticSearch = (event) => {
        fetch('http://127.0.0.1:8000/search/', {
            method: 'post',
            headers:{'Content-Type': 'application/json'},
            body: JSON.stringify({
                q: event.target.value 
            })
    })
    .then(response => response.json())
    .then(res => {
        console.log(res)
        this.setState({ data: res })
    });  
    }

   getPage = page => {
      console.log("page from child component:", page);
   }




    render(){
        return (
            <div className="api-body">
                <section>
                    <div className="tc pa2">
                        <input
                            type="button"
                            className="br2 center ph3 pv2 input-reset ba b--black bg-transparent grow pointer f6 dib"
                            value="Post"
                            onClick={() => this.openModal()} 
                        />
                        <input
                            className="db ma3 q center border-box hover-black w-100 measure ba b--black-20 pa2 br2 mb2"
                            type="text"
                            name="q"
                            id="q"
                            onChange = {this.elasticSearch}
                        />
                        </div>
                        <Modal 
                            visible={this.state.visible}
                            width="400"
                            height="300"
                            effect="fadeInDown"
                            onClickAway={() => this.closeModal()}
                        >
                        <div className="mv3 pa3">

                        <label className="db fw6 lh-copy f6" htmlFor="password">Title</label>
                        <input
                            className="db border-box hover-black w-100 measure ba b--black-20 pa2 br2 mb2"
                            type="text"
                            name="title"
                            id="title"
                            onChange={this.onTitleChange}
                        />
                    </div>
                    <div className="mv3 pa3 mt-1">
                        <label htmlFor="comment" className="f6 b db mb2">Contents </label>
                        <textarea 
                            id="content" 
                            name="content" 
                            className="db border-box hover-black w-100 measure ba b--black-20 pa2 br2 mb2" 
                            aria-describedby="content-desc"
                            onChange={this.onContentChange}>
                        </textarea>
                    </div>
                    <div className="mv3 pa3 mt-1">
                    <input
                        type="file"
                        multiple = {false}
                        id="img"
                        name="img"
                        ref={(input) => { this.inpuElement = input; }}
                        accept=".jpg,.jpeg,.png,.pdf,.doc"
                        onChange={this.OnFileChange}
                        />
                    <input
                        type="button"
                        className="br2 center ph3 pv2 input-reset ba b--black bg-transparent grow pointer f6 dib"
                        value="Submit"
                        onClick={this.SubmitProfile} 
                        />
                    </div>
                    </Modal>
                </section>

               <ProfileCard 
                data={this.state.data}
                pages={this.state.pages}
                page={this.state.page}
                getPage={this.getPage}
                />
            </div>
        )
    }
}


export default Api;

Child Component

import React from 'react';
class ProfileCard extends React.Component {
  constructor(props){
    super(props)
    this.state = {
      data : []
    }
  }

  deleteProfile = id => e => {
    fetch('http://127.0.0.1:8000/delete_profile/', {
      method: 'post',
      headers:{'Content-Type': 'application/json'},
      body: JSON.stringify({
        id: id
      })
    })
    .then(response => response.json())
    .then(res => {
        if (res.code === 200){
          this.componentDidMount()
        }
        console.log(res)
    })
  } 

  demoMethod(page){
    this.props.getPage(page)
    console.log(page)
  }

  render(){
  return (
    <div>
      {
      this.props.data.map((user,i) => {
        return (
          <article className='mw5 tc bg-white dib br3 pa3 ma3 pa4-ns mv3 ba b--black-10 shadow-5 pc-scroll pointer' key={i}>
          <div className="tc">

           <img 
              src={"http://127.0.0.1:8000" + user.photo}
              className="br-100 h3 w3 dib" 
              alt="profile pic"
              onDoubleClick = {this.deleteProfile(user.id)}
          />
             <h1 className="f4">{user.title}</h1>
             <hr className="mw3 bb bw1 b--black-10" />
           </div>
           <p className="lh-copy measure center f6 black-70">
           {user.content}
           </p>
         </article>
        );
      })
    }

      <div className="pagination">
        <center>
            {[...Array(this.props.pages+1)].map((x, i) =>
              <h2 key={i} onClick={()=>this.demoMethod(i+1)} className="tc">{ i+1 }</h2>
            )}
        </center>
      </div>

    </div>
  );
  }
}


export default ProfileCard;
Sign up to request clarification or add additional context in comments.

Comments

1

You are not passing page prop as function, it should be a function instead of variable, page is number in state. You should send:

someFunction = () => {
 console.log('function passed from parent')
}
// in render function
<ProfileCard 
      data={this.state.data}
      pages={this.state.pages}
     page={this.someFunction}
/>

2 Comments

Yes. there is no requirements to send it in function . so is there any way??
If you want to send data from child to parent, way is to pass function as prop to child and then pass data as argument to that function.
0

In this case, your data should reside in parent components state and you should be passing a handler down to child component has props and use that handler to update the state in parent component.

1 Comment

could you please write it
0

Add a call Back function to your parent component - See below constructor

    class Api extends React.Component {
        constructor(props) {
            super(props);
            this.state = {
                title : '',
                content: '',
                img: '',
                data: [],
                pages: 0,
                page:0

            }
        }
        **##Add callback function**
        myCallbackfunc(val){
         this.setState({page:val)}
         }

        OnFileChange = (event) => {
            this.setState({img: event.target.files[0]});
        }

        onTitleChange = (event) => {
            this.setState({title: event.target.value})
        }

        onContentChange = (event) => {
            this.setState({content: event.target.value})
        }

        resetForm = () => {
            document.getElementById('title').value = '';
            document.getElementById('content').value = '';
            document.getElementById('img').value = '';
        }

        openModal() {
            this.setState({
                visible : true
            });
        }

        closeModal() {
            this.setState({
                visible : false
            });
        } 


        componentDidMount() {
            fetch(`http://127.0.0.1:8000/get_profile/?page=${this.state.page}`)
              .then(response => response.json())
              .then(res =>{
                this.setState({ data: res });  
                this.setState({ pages: res[res.length-1].pages });
                console.log(this.state.page)   
            });
          }


        SubmitProfile = (event) => {
            let formData = new FormData();
            formData.append('img',this.state.img);
            formData.append('title',this.state.title);
            formData.append('content',this.state.content);
            fetch('http://127.0.0.1:8000/post_profile/', {
                method: 'post',
                headers: {
                    Accept: 'application/json, text/plain, */*'
                  },
                  body:formData,
              })
              .then(response => response.json())
              .then(res => {
                  if (res.code === 200){
                    this.componentDidMount()
                    this.resetForm()
                    this.closeModal()
                  }
                  console.log(res);
              })
        }


        elasticSearch = (event) => {
            fetch('http://127.0.0.1:8000/search/', {
                method: 'post',
                headers:{'Content-Type': 'application/json'},
                body: JSON.stringify({
                    q: event.target.value 
                })
        })
        .then(response => response.json())
        .then(res => {
            console.log(res)
            this.setState({ data: res })
        });  
        }





        render(){
            return (
                <div className="api-body">
                    <section>
                        <div className="tc pa2">
                            <input
                                type="button"
                                className="br2 center ph3 pv2 input-reset ba b--black bg-transparent grow pointer f6 dib"
                                value="Post"
                                onClick={() => this.openModal()} 
                            />
                            <input
                                className="db ma3 q center border-box hover-black w-100 measure ba b--black-20 pa2 br2 mb2"
                                type="text"
                                name="q"
                                id="q"
                                onChange = {this.elasticSearch}
                            />
                            </div>
                            <Modal 
                                visible={this.state.visible}
                                width="400"
                                height="300"
                                effect="fadeInDown"
                                onClickAway={() => this.closeModal()}
                            >
                            <div className="mv3 pa3">

                            <label className="db fw6 lh-copy f6" htmlFor="password">Title</label>
                            <input
                                className="db border-box hover-black w-100 measure ba b--black-20 pa2 br2 mb2"
                                type="text"
                                name="title"
                                id="title"
                                onChange={this.onTitleChange}
                            />
                        </div>
                        <div className="mv3 pa3 mt-1">
                            <label htmlFor="comment" className="f6 b db mb2">Contents </label>
                            <textarea 
                                id="content" 
                                name="content" 
                                className="db border-box hover-black w-100 measure ba b--black-20 pa2 br2 mb2" 
                                aria-describedby="content-desc"
                                onChange={this.onContentChange}>
                            </textarea>
                        </div>
                        <div className="mv3 pa3 mt-1">
                        <input
                            type="file"
                            multiple = {false}
                            id="img"
                            name="img"
                            ref={(input) => { this.inpuElement = input; }}
                            accept=".jpg,.jpeg,.png,.pdf,.doc"
                            onChange={this.OnFileChange}
                            />
                        <input
                            type="button"
                            className="br2 center ph3 pv2 input-reset ba b--black bg-transparent grow pointer f6 dib"
                            value="Submit"
                            onClick={this.SubmitProfile} 
                            />
                        </div>
                        </Modal>
                    </section>

                   <ProfileCard 
                    data={this.state.data}
                    pages={this.state.pages}
                    page={this.state.page}
#Pass the call back function as a prop to the child component
                    mycallbackfunc = {this.myCallbackfunc)
                    />
                </div>
            )
        }
    }        
    export default Api;

To your child component, in the demoMethod function add this line

demoMethod(page){
Change the below line
this.props.myCallbackfunc(page)
console.log(page)
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.