How to use the "parent" component function in the React child

Asked

Viewed 871 times

-1

I have a component Menu

import React, { Component } from "react";
import "./Menu.css";
import { connect } from "react-redux";
import Sidebar from "react-sidebar";
import SidebarContent from "./sidebar_content";
import MaterialTitlePanel from "./material_title_panel";
import { Button } from "react-bootstrap";

const styles = {
  contentHeaderMenuLink: {
    textDecoration: "none",
    color: "white",
    padding: 0
  },
  content: {
    padding: "0px",
    height: "0px"
  }
};

class Menu extends Component {

  constructor(props) {
    super(props);

    this.state = {
      docked: false,
      open: true,
      transitions: true,
      touch: true,
      shadow: false,
      pullRight: false,
      touchHandleWidth: 20,
      dragToggleDistance: 30
    };

    this.renderPropCheckbox = this.renderPropCheckbox.bind(this);
    this.renderPropNumber = this.renderPropNumber.bind(this);
    this.onSetOpen = this.onSetOpen.bind(this);
    this.menuButtonClick = this.menuButtonClick.bind(this);
    this.closeMenu = this.closeMenu.bind(this);
  }

  onSetOpen(open) {
    this.setState({ open });
  }

  getOpenStatus() {
    return this.setState;
  }

  menuButtonClick(ev) {
    ev.preventDefault();
    this.onSetOpen(!this.state.open);
  }

  closeMenu() {
    this.onSetOpen(false);
  }

  renderPropCheckbox(prop) {
    const toggleMethod = ev => {
      const newState = {};
      newState[prop] = ev.target.checked;
      this.setState(newState);
    };

    return (
      <p key={prop}>
        <label htmlFor={prop}>
          <input
            type="checkbox"
            onChange={toggleMethod}
            checked={this.state[prop]}
            id={prop}
          />
          {prop}
        </label>
      </p>
    );
  }

  renderPropNumber(prop) {
    const setMethod = ev => {
      const newState = {};
      newState[prop] = parseInt(ev.target.value, 10);
      this.setState(newState);
    };

    return (
      <p key={prop}>
        {prop}{" "}
        <input type="number" onChange={setMethod} value={this.state[prop]} />
      </p>
    );
  }

  render() {
    const sidebar = (
      <SidebarContent
        isPermissaoCOREC={this.props.isPermissaoCOREC}
        isPermissaoADM={this.props.isPermissaoADM}/>
    );

    const contentHeader = (
      <div>
        {!!this.getOpenStatus() ? (
          <div id="headerBlock">
            {!this.state.docked && (
              <Button
                onClick={this.menuButtonClick}
                href="#"
                style={styles.contentHeaderMenuLink}
                className="buttonMenu"
              >
                <i className="material-icons button-menu-icon">menu</i>
              </Button>
            )}
          </div>
        ) : (
          <></>
        )}
      </div>
    );

    const sidebarProps = {
      sidebar,
      docked: this.state.docked,
      sidebarClassName: "custom-sidebar-class",
      contentId: "custom-sidebar-content-id",
      overlayId: "sidebar-overlay",
      open: this.state.open,
      touch: this.state.touch,
      shadow: this.state.shadow,
      pullRight: this.state.pullRight,
      touchHandleWidth: this.state.touchHandleWidth,
      dragToggleDistance: this.state.dragToggleDistance,
      transitions: this.state.transitions,
      onSetOpen: this.onSetOpen
    };

    return (
        <Sidebar {...sidebarProps}>
          <MaterialTitlePanel title={contentHeader}></MaterialTitlePanel>
        </Sidebar>
    );
  }
}

const mapStateToProps = state => ({
  isPermissaoCOREC: state.authentication.isPermissaoCOREC,
  isPermissaoADM: state.authentication.isPermissaoADM
});

export default connect(mapStateToProps)(Menu);

And a component SidebarContent:

import React from "react";
import PropTypes from "prop-types";
import MaterialTitlePanel from "./material_title_panel";
import { NavLink } from "react-router-dom";

const styles = {
  sidebar: {
    width: 256
  },
  content: {
    backgroundColor: "white",
    opacity: 1,
    overflowY: "auto"
  }
};

const scrollDown = () => {
  window.document
    .getElementsByClassName("custom-sidebar-class")[0]
    .scrollTo(
      0,
      window.document.getElementsByClassName("custom-sidebar-class")[0]
        .scrollHeight
    );
};

const scrollUp = () => {
  window.document
    .getElementsByClassName("custom-sidebar-class")[0]
    .scrollTo(0, 0);
};

const shouldShowScroll = size => {
  if (size + 1 > 6) {
    return true;
  }
  return false;
};

const arrayItens = props => {
  let menuItens = [
    <NavLink
      key="1"
      to="/consulta"
      className="nav-link consultas"
      activeClassName="nav-link-active consultas-azul"
    >
      <div style={{ textAlign: "center" }}>
        <p className="nav-menu-texto" style={{ marginTop: "20%" }}>
          Consultas
        </p>
      </div>
    </NavLink>,
    <NavLink
      key="2"
      to="/conteudo"
      className="nav-link formulario"
      activeClassName="nav-link-active formulario-azul"
      onClick={close}
    >
      <div style={{ textAlign: "center" }}>
        <p className="nav-menu-texto" style={{ marginTop: "20%" }}>
          Formulários
        </p>
      </div>
    </NavLink>,
    <NavLink
      key="3"
      to="/avisos"
      className="nav-link avisos"
      activeClassName="nav-link-active avisos-azul"
    >
      <div style={{ textAlign: "center" }}>
        <p className="nav-menu-texto" style={{ marginTop: "20%" }}>
          Avisos
        </p>
      </div>
    </NavLink>
  ];

  if (props.isPermissaoCOREC || props.isPermissaoADM) {
    menuItens.push(
      <NavLink
        key="4"
        to="/desbloqueio"
        className="nav-link desbloquear"
        activeClassName="nav-link-active desbloquear-azul"
      >
        <div style={{ textAlign: "center" }}>
          <p className="nav-menu-texto" style={{ marginTop: "20%" }}>
            Desbloquear
          </p>
        </div>
      </NavLink>
    );
  }

  if (props.isPermissaoCOREC || props.isPermissaoADM) {
    menuItens.splice(
      0,
      0,
      <NavLink
        key="5"
        to="/solicitacoes"
        className="nav-link solicitacoes"
        activeClassName="nav-link-active solicitacoes-azul"
      >
        <div style={{ textAlign: "center" }}>
          <p className="nav-menu-texto" style={{ marginTop: "20%" }}>
            Solicitações
          </p>
        </div>
      </NavLink>
    );
  }

  let inicio = 0;

  return menuItens.slice(inicio, inicio + 12);
};

const SidebarContent = props => {
  return (
    <MaterialTitlePanel style={{ textAlign: "center" }}>
      <div style={styles.content}>
        {shouldShowScroll(arrayItens(props).length) ? (
          <div className="row">
            <button onClick={scrollDown} className="button-go down">
              <i className="material-icons">keyboard_arrow_down</i>
            </button>
          </div>
        ) : (
          <></>
        )}
        {console.log("props: ", props)}
        <NavLink
          to="/minha-area"
          className="nav-link minha-area"
          activeClassName="nav-link-active minha-area-azul"
          style={
            shouldShowScroll(arrayItens(props).length)
              ? { marginTop: "32px" }
              : {}
          }
        >
          <div style={{ textAlign: "center" }}>
            <p className="nav-menu-texto" style={{ marginTop: "20%" }}>
              Minha Área
            </p>
          </div>
        </NavLink>

        {/* <button className="openedMenuButton" style={{float:'right'}}>
            <i className="material-icons white-text arrow-left">
              keyboard_arrow_left
            </i>
        </button> */}
        {arrayItens(props)}

        {shouldShowScroll(arrayItens(props).length) ? (
          <div className="row">
            <button onClick={scrollUp} className="button-go up">
              <i className="material-icons">keyboard_arrow_up</i>
            </button>
          </div>
        ) : (
          <></>
        )}
      </div>
    </MaterialTitlePanel>
  );
};

SidebarContent.propTypes = {
  style: PropTypes.object
};

export default SidebarContent;

How to call the function closeMenu of Menu within the component SidebarContent?

I tried to pass as property but it didn’t work, there is some correct way to do it?

1 answer

2


The most typical way is to pass through the props, but be careful not to invoke the function instead of passing it. Another issue you should be aware of is the context. Because of this I recommend that you pass the function using Arrow Function. Ex.: () => {closeMenu()}

In the component Menu

<SidebarContent 
    isPermissaoCOREC={this.props.isPermissaoCOREC}
    isPermissaoADM={this.props.isPermissaoADM}
    onPressClose={() => {closeMenu()}}
/>

In the component SidebarContent

<NavLink
  key="2"
  to="/conteudo"
  className="nav-link formulario"
  activeClassName="nav-link-active formulario-azul"
  onClick={this.props.onPressClose}
>

How you’ll be using Arrow Function you won’t need this.closeMenu = this.closeMenu.bind(this);

  • If you have the bind function it may not work?

  • With the bind function (inserted as you did there in the constructor) you enter the function without calling it. Ex.: onPressClose={() => {this.closeMenu}}. You can also do onPressClose={this.closeMenu.bind(this)}

  • With the bind it was not, but in its form it was more or less.. type: ?

  • 1

    You solved part of my problem, thanks.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.