I have a section that is made out of 2 components:
trigger component
show/hide component
Basically when I click on trigger component, new component under will appear. This is handled simple by useState
const [toShow, setToShow] = useState(0);
And then I am using onClick method:
onClick={() => setToShow(1)}
Showing the element under trigger component:
{toShow === 1 && (
<div className="show-box" id="myHiddenComponent">
<HiddenComponent />
</div>
)}
Problem is, I need to access the hidden component with id="myHiddenComponent" from my Navbar. That means, the component will be not set to show. But link should understand that it has to set it to be opened and then scroll to the component. Is something like that possible with React ?
Right now I am using Hashlink
<HashLink smooth to='#myHiddenComponent'>
GO TO HIDDEN SECTON
</HashLink>
But that does not work unfortunately, since the section is hidden.
you need to set state of toShow to 1 onClick on HashLink component
Related
I want to delete a list, and style that button with an icon. If I just have "delete" as my button, my onClick returns the ID as expected. However, when I try to use a component for my button, it returns a weird object.
I tried using different elements instead of a <Button/> and different icon libraries, but it results in the same behavior. This is how I was importing the component and I am using styled-components if that matters.
import React from "react";
import { Draggable } from "react-beautiful-dnd";
import {BsXCircle} from "react-icons/bs"
import styled from 'styled-components'
Below is my code for my component that renders the list's title, and a button that would delete the list:
<div
{...provided.draggableProps} {...provided.dragHandleProps} ref={provided.innerRef}>
<div value={props.list._id} onClick = {props.handleListSelect} className="list">
<button value={props.list._id} onClick={props.handleDeleteList} >
<BsXCircle/>
</button>
{props.list.title}
</div>
</div>
The code snipper below works as expected.
<button value={props.list._id} onClick={props.handleDeleteList} >
delete
</button>
My props.handleDeleteList function is below:
const deleteList = async (e) =>{
console.log(e.target.value)
}
If I use <BsXCircle/> , my console log is this:
{stringValue: '"undefined"', valueType: 'string', kind: 'ObjectId', value: 'undefined', path: '_id', …}
I am confused of why this is happening.
Isn't my value that I am passing assigned in the value attribute of my button? Why does rendering a component instead of a text change the value of my button?
I have simplified my code just for asking this question.
First thing, the <button/> element should accept only certain types of nested elements: MDN ref
Permitted content Phrasing content but there must be no Interactive content
That said, your problem is that nested elements of <button/> inherit its event listeners, so when you nest the react-icon Component ( an <svg> I guess ), and click on the button, you basically are dispatching the click event on the svg and not on the <button/>. You can address the issue with a simple css fix:
button > * {
pointer-events: none;
}
This way you are disabling all event listeners on button's children and it should fix it.
I'm currently learning React, and trying to get a sense of how components re-render. I have this parent component which renders three items. Each item just renders an <li>
function App() {
console.log("Parent Rerendered");
return (
<div>
<ul>
<Item1 />
<Item2 />
<Item3 />
</ul>
</div>
);
}
Item2 is a bit different because it also renders an "x" that will un-render the component when it's clicked:
function Item2() {
const [visible, setVisible] = useState(true);
const makeInvisible = () => {
setVisible(false);
};
console.log("Item 2 Rerendered");
return visible ? (
<div>
<li>
Second Item <span onClick={makeInvisible}>X</span>
</li>
</div>
) : null;
}
When I test this in my browser and click the "x", I can see from the console that Item2 gets re-rendered. However, none of the other components get re-rendered including the parent component. However the parent component does change, so how does this happen without re-rendering it.
If that's a bit confusing, here's an illustration of the initial state, my expectations, and reality. What am I misunderstanding about how React re-renders components?
A component rerenders when it sets state, or when its parent rerenders1. App has no state and no parent, so it will never rerender. It doesn't need to though. React saves the virtual DOM from the previous render, so it still knows that App is supposed to be a div surrounding a ul surrounding an Item1, Item2, and Item3. If the Item2 rerenders, and returns a null instead of a div, react will update the part of the real DOM that the Item2 is responsible for, by removing the div. The rest of the page remains intact
1) or if a context it consumes changes, or in a class component when you call forceUpdate. But for most cases, it's just state and parent that matter.
Instead of clicking onto <Item2 /> go to the Dev-tools -> Explorer -> select the Element and press delete. The view will also change, the gap will close, without react being involved at all.
React is responsible to update the DOM, the layout is done by the browser. So when <Item2 /> decides it wants to be rendered as null instead of a div>li (??? invalid markup ) and therefore removes the respective DOM-nodes, the browser will update the layout.
And the parent component has nothing to do with all that.
I'm using a component library and I cannot figure this out. I'm new to react and javascript and need help.
There is a component in the library that renders a header panel with tabs.
Component
|_Component.Tab
The Tab component has 2 states that change its appearance when it is clicked. But the click handler and state changes have to be defined by me outside of Tab component. How do I do this?
Seems to me by your question that you need to use props to pass the function to change state from the Component to the Tabs. Something like this:
Component
changeState(value) {
this.setState({ appearance: value });
}
render() {
return (
<div>
<Tab
appearance={this.state.appearance}
onChangeState={this.changeState}
/>
</div>
);
}
Tab
render() {
console.log('Appearance: ', this.props.appearance); // Use it for whatever you need it
return (
<div>
<Button
onClick={(value) => this.props.onChangeState(value)} />
</div>
);
}
Not sure why do you want to handle a function and it’s state outside of the component when it has to be within the Tab component. But here is the solution what you actually have to do in your Tab component to handle your state
Bind your handler function inside a constructor like below
Eg:
this.handlerFunction = this.handlerFunction.bind(this)
Call this.handlerFunction reference in your tab onClick
Eg:
onClick={this.handlerFunction}
Set state in handlerFunction
Eg:
handlerFunction(event){
this.setState({
tabClicked: event.target.value
})
}
Else I guess The outside component should be a child component that you are talking about. If so pass your tab click state as props to your outside component (i.e., child component) and receive that state as props in your child component and do setState there.
If you are still unclear then
Post your component code here. With Just theory it’s little difficult to understand the actual problem that you are talking about.
I have created bootstrap modal component in react.
var carModal=<Modal handleHideModal={this.handleHideCarModal}
onConfirm={this.confirmCarModal}
title="Car"
id="CarModal">
<CarStructure callbackParent={this.showCarOptionsUpdate}/>
</Modal>
In car structure I have a form where based on button click I want to remove <CarStructure> child component from the modal carModal and update it with another component with different form structure. How can I replace <CarStructure> with another component having totally different user interface and options?
Remember that the job of a React component's render function is to describe how the component should look at any given point at time, so you don't "remove" or "change" pieces of the DOM so much as you describe when they should change themselves. So, you'll want to base the internal component of <Modal> on some sort of state (which may change throughout the life of the parent component). Something like this might do the trick:
var carModalBody;
if (this.state.something) {
var carModalBody = <CarStructure callbackParent={this.showCarOptionsUpdate} />;
} else {
var carModalBody = <SomeOtherComponent />;
}
var carModal = <Modal handleHideModal={this.handleHideCarModal}
onConfirm={this.confirmCarModal}
title="Car"
id="CarModal">
{carModalBody}
</Modal>
I have a tabbed menu on my page, which is basically a bunch of divs that get shown/hidden depending on the tab that's clicked. I want to be able to refetch the data in a React Component in one of the divs once it appears.
componentDidMount fires at the very beginning, so it's not an option. It would be nice to just have an HTML event onShow similar to onClick but nothing like that seems to exist.
Any suggestions?
I have a Tabs component but in my case, all tabs content are mounted but not displayed. When I click on a tab, I just change the visibility with css
But to refetch data, you should make a component for the containers that fetch the data in his componentDidMount so, in the top level if you switch which one renders, the componentDidMount will trigger.
Put some code if you want some help with your case
Per the docs, componentDidUpdate is probably what you're looking for. It's called after props and/or state has changed and the component has re-rendered (not called for the initial render).
That said, it's probably simpler to just handle the data fetching in the onClick handler itself or better yet, fetch the data once in the parent component and pass down the relevant slice of data to the tabs and then show / hide as appropriate.
Hey You have to separate out the tab as component and render those component based on tab changed let me give one example over here.
Suppose I have one Page called MainPage in that Page I have Tab Control which Contain the Three tab First,Second and Third.
first you have to create a three Component like
var First=React.createClass({ // First Tab Content goes here });
var Second=React.createClass({// Second Tab Content goes here});
var Second=React.createClass({// Third Tab Content goes here});
Now your MainPage Should look like
var MainPage=React.createClass({
onClick:function(e)
{
if($(e.target).attr('id')=="1")
{
React.render(<First />,document.getElementById('tab-content'));
}
else if($(e.target).attr('id')=="2")
{
React.render(<Second />,document.getElementById('tab-content'));
}
if($(e.target).attr('id')=="3")
{
React.render(<Third />,document.getElementById('tab-content'));
}
},
render:function()
{
return(
<div>
<div>
//Three Tabl goes here
<div id="1" onClick={this.HandleTab}>Tab 1</div>
<div id="2" onClick={this.HandleTab}> Tab 2</div>
<div id="3" onClick={this.HandleTab}>Tab 3</div>
</div>
//your Container Div
<div id="tab-content">
</div>
</div>
)
}
})