Skip to content Skip to sidebar Skip to footer

Get Closest Parent Element By Class Name In React

Using React, how do I refer to parent element's closest element with certain classname? Code below: const Skill = props => (

Solution 1:

You can use State in functional components like so:

constSkills = ({ skills, loading }) =>
  loading ? (
    'loading'
  ) : (
    <div>
      {skills.map(skill => (
        <SkillContainerkey={skill._id}skill={skill} />
      ))}
    </div>
  )

constSkill = ({ skill, open, toggle }) => (
  <div><h4onClick={toggle}>
      skill: {skill.completed} {skill.id}
    </h4>
    {open && <div>{skill.title}</div>}
  </div>
)

constSkillContainer = ({ skill }) => {
  const [open, setOpen] = React.useState(false)
  const toggle = React.useCallback(
    () =>setOpen(open => !open),
    []
  )
  returnReact.useMemo(
    () =>Skill({ skill, open, toggle }),
    [open, skill, toggle]
  )
}
//savety to not set state when component is no longer mountedconstuseIsMounted = () => {
  const isMounted = React.useRef(false)
  React.useEffect(() => {
    isMounted.current = truereturn() => (isMounted.current = false)
  }, [])
  return isMounted
}

constSkillsContainer = () => {
  const [result, setResult] = React.useState({
    loading: true,
    data: []
  })
  const isMounted = useIsMounted()
  React.useEffect(() => {
    constfetchData = () => {
      //cannot use async await here because Stack Overflow//  uses old babel
      axios
        .get('https://jsonplaceholder.typicode.com/todos')
        .then(result => {
          if (isMounted.current) {
            //do not set data if component is no longer mountedsetResult({
              loading: false,
              data: result.data
            })
          }
        })
    }
    fetchData()
  }, [isMounted])

  returnReact.useMemo(
    () =>Skills({
        skills: result.data,
        loading: result.loading
      }),
    [result]
  )
}

//render appReactDOM.render(
  <SkillsContainer />,
  document.getElementById('root')
)
<scriptsrc="https://cdnjs.cloudflare.com/ajax/libs/axios/0.19.2/axios.min.js"></script><scriptsrc="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.4/umd/react.production.min.js"></script><scriptsrc="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.4/umd/react-dom.production.min.js"></script><divid="root"></div>

The class version is a little more verbose:

classSkillsContainerextendsReact.PureComponent {
  state = {
    loading: true,
    //should do error here as wellresult: []
  }
  fetchData = (
    length //arrow function auto bind to this) =>newPromise(r =>setTimeout(() =>r(length), 2000)
    ).then(l =>this.setState({
        loading: false,
        result: [...newArray(l)].map((_, i) => i+1)
      })
    )
  //if your skills array changes based on props:// example here: https://reactjs.org/docs/react-component.html#componentdidupdatecomponentDidUpdate(prevProps) {
    if (this.props.length !== prevProps.length) {
      this.fetchData(this.props.length)
    }
  }
  //fetch data on mountcomponentDidMount() {
    this.fetchData(this.props.length)
  }
  render() {
    returnthis.state.loading
      ? 'loading'
      : Skills({ skills: this.state.result })
  }
}
constSkills = ({ skills }) => (
  <div>
    {skills.map((skill, id) => (
      <SkillContainerkey={id}skill={skill} />
    ))}
  </div>
)
constSkill = ({ skill, open, toggle }) => (
  <div><h4onClick={toggle}>skill: {skill}</h4>
    {open && <div>extra</div>}
  </div>
)

classSkillContainerextendsReact.PureComponent {
  state = {
    open: false
  }
  toggle() {
    this.setState({
      open: !this.state.open
    })
  }
  render() {
    returnSkill({
      skill: this.props.skill,
      open: this.state.open,
      toggle: this.toggle.bind(this)
    })
  }
}
//render appReactDOM.render(
  <SkillsContainerlength={2} />,
  document.getElementById('root')
)
<scriptsrc="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.4/umd/react.production.min.js"></script><scriptsrc="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.4/umd/react-dom.production.min.js"></script><divid="root"></div>

The code uses conditional rendering but you can use props to set className as well

Solution 2:

I would like to pass the skill body element ref to the Parent so that you can handle the style for the element. Hope the below code would done the thing which you need.

classSkillextendsReact.Component {

    render() {
        return (
            <divclassName="skill-card"><divclassName="skill-header"><divclassName="skill-header-icon"><divonClick={() => this.props.click(this.skillBodyEle)}>Header Icon</div></div></div><divref={e => this.skillBodyEle = e}
            className="skill-body">
                Skill Body
            </div></div>
            );
    }
}

classSkillsextendsReact.Component {
    handleClick = (skillBodyEle) => {
        if (skillBodyEle.hidden) {
            skillBodyEle.hidden = false;
        } else {
            skillBodyEle.hidden = true;
        }
      };
      render() {
          return (
          <Skillclick={this.handleClick} 
          />
          );
      }
}

Post a Comment for "Get Closest Parent Element By Class Name In React"