I have a containerElement and a react component. I want to add the react component into the containerElement. Is there a way I can do it? I have tried containerElement .appendChild(), but not working.
const containerElement = document.getElementById(divId);
React component: <ReactComponent></ReactComponnet>
ReactDOM.render(<ReactComponent/>, document.getElementById(divId));
Following the React lifecycles, you shouldn't have to insert the component into your parent component (containerElement). The react component should be inserted in the normal flow as a child or grandchild of the parent component.
If I'm understanding your question correctly, you need to handle the case where you are getting the DOMElement outside the normal flow of the React lifecycle. For that you can use refs.
For example below, define the component you're trying to insert somewhere in the render lifecycle of your container. No matter how nested the child is, you can "get" the child DOM element just like you are trying to do with document.getElementById from your question.
class Parent extends React.Component {
constructor(props) {
super(props);
this.myRef = React.createRef();
}
render() {
return (
<FunctionComponent ref={this.myRef} />
);
}
}
Hope this helps
Related
I am coding a checkers web app and have set up user interaction by placing onclick functions on the components. I have two different components pieces and spaces. Ideally, the onclick functions are linked to methods in the parent component which interpret the state of the component being clicked and responds by returning data back to the component or a separate component. The issue is, I do not understand how to send data to child components from the parent following the mounting of said child component. I understand you can use props to initialize the state in a child component, but is there anyway I can update the child component from the parent following this initialization? I am new to react so I'm not exactly sure how inter component communication works quite yet.
You can pass update function to child, I hope this helps.
Parent
import React, { Component } from 'react'
export default class Parent extends Component {
constructor(props) {
super(props);
this.state={
something:""
}
}
updateSomething = (anotherThing) => {
this.setState({something:anotherThing})
}
render() {
return (
<div>
{/* we are passing updateSomething function in props*/}
<ChildComponent updateSomething={(anotherThing)=>this.updateSomething(anotherThing)}/>
</div>
)
}
}
Child
import React, { Component } from 'react'
export default class ChildComponent extends Component {
render() {
return (
<div>
{/* we are using updateSomething function to update parents state*/}
<button onClick={()=>this.props.updateSomething("anotherThing")}>Update Parents state</button>
</div>
)
}
}
I am getting stuck while using react, wherein, I am passing a function from a parent component to multiple children components. That function calls other functions that also reside within the parent component.
The children components do successfully start the function, but unfortunately, the function fails because it seems to not have the same context from within the children's elements, eg. it begins calling the other functions stored within the parent element, and receives undefined. This is strange because the error is coming from the parent component file, not the child component file.
I was not sure whether to pass all the functions to the children elements, which feels rather bulky, and also feels like I would still be missing important function context.
I have tested running the same function on the parent component and it has no issues, almost like the function context from the parent component is not passed to the child component, only the function itself.
Is that correct?
Here is an example where the child component has a button to click that would run the function that was passed from the parent component and includes running other functions from within the parent component, updating state and making changes, etc.
Parent element:
class Content extends Component {
constructor(props) {
super(props);
this.state = {
name: "React",
toggle: true,
...
};
}
toggleComponent(name) {
this.toggling(name); // THIS IS WHERE THE ERROR OCCURS ON THE CHILD ELEMENT, undefined.
}
toggling(name) {
does some stuff...
}
render() {
return (
<Comp toggleComponent={this.toggleComponent}/>
)
}
Child element:
class Demo1 extends Component {
constructor(props) {
super(props);
this.state = {
name: "React"
};
}
render() {
return (
<div className="button" onClick={() => this.props.toggleComponent('theCompName')}>Continue</div>
)
Let me know what can be done to pass the additional context to the children components or if there is a better way to do this.
Thanks, you are all very smart.
In your constructor for your Content class, try binding your toggleComponent function to the class using .bind():
constructor(props) {
super(props);
this.state = {
name: "React",
toggle: true,
...
};
this.toggleComponent = this.toggleComponent.bind(this);
}
Class methods are not "bound" to the class by default. This means that your this keyword in toggleComponent does not refer to the Content class until you specify it using .bind().
Hope this helps!
More info can be found here: https://reactjs.org/docs/handling-events.html
Use arrow syntax in the parent component's functions. That will allow the functions in the parent component to execute in the parent component's context. Otherwise you'll have to do a bunch of binding(this) crap to make that work properly.
What should be the best approach to pass form.control's input with defaultValue(I needed to display what to edit) that has been edited. I was using refs(following one of the answer here) but it only works on self component. Tried to implement to Child to Parent but didn't work. Snippet of essential codes below:
Child.js
<Form.Control
ref={this.props.categoryNewValue}
defaultValue={this.props.categoryValue}
onChange={this.props.handleAssetChange}/>
Parent.js
class App extends Component{
constructor(props){
super(props);
this.state = {
assetItems:[],
assetItemID:"",
assetItemsToEdit:[],
categoryItems:[]
}
this.categoryNewValue = React.createRef();
}
handleAssetChange=(event)=>{
this.setState({
categoryNewValue: this.categoryNewValue.current.value
})
console.log(this.categoryNewValue)
}
render(){
return(
<Router>
<Route path='/Assets'>
<ViewAssets categoryNewValue={this.state.categoryNewValue}
handleAssetChange={this.handleAssetChange}
/>
</Route>
</Router>
)
}
}
export default App;
Remember that data always flows downwards from your logical units in the parent to the DOM nodes. Why not just pass the parent state to the child through props?
Parent.js (render function):
<ViewAssets pstate={this.state} />
I don't see any of the logic you used to setup and focus the refs on your child elements, but if you still want to see what that model would look like I recommend this guide and the react docs on forwarding refs.
I am using React with Typescript and would like to know how to figure out the coordinates of a sub-component in a React class I wrote.
I already found this article: https://medium.com/#chung.andrew7/finding-the-absolute-positions-of-react-components-fda1c5bc9ab
And this: Get div's offsetTop positions in React
Here it is stated that this is usually done with getBoundingClientRect(), but I can't find any way how to do this with TypeScript, or what property or a ref this would be located on.
If I assign my component as _searchBarPreview: React.RefObject<{}>; by passing the following as "ref" prop on the element:ref={this._searchBarPreview}, I can't access the said function on that object at all.
What works is to assign the child component I want to get clients of an id and obtain the coordinates via:
document.getElementById('blablablablabla').getBoundingClientRect();
but there HAS to be a better way.
Any quick guidance?
Seem like that is the only way or you can use react-dom
class MyComponent extends React.Component {
constructor(props) {
super(props)
this.myRef = React.createRef()
const data = ReactDOM
.findDOMNode(this.myRef)
.getBoundingClientRect();
}
render() {
return <div ref={this.myRef} />
}
}
I'm new to react, and am a little confused about something. I've read many articles online claiming that a component cannot alter its own props, but that a parent can alter the props of its children. However, I have seen nothing that actually shows how to do this.
I would like to be able to do this:
class Parent extends Component {
constructor(props) {
super(props);
this.childProps = {name:'name',age:12,type:'child'};
this.changeChild = this.changeChild.bind(this);
}
changeChildName(newName) {
//change prop 'name' of child here;
}
render() {
return (
<Child {...this.childProps} />
);
}
}
However, I can't figure out how to do this at all - despite almost all the material that I've read on React saying that a parent can change its child's props. What I can get to work properly is as follows:
class Parent extends Component {
constructor(props) {
super(props);
this.state = {name:'name',age:12,type:'child'};
this.changeChild = this.changeChild.bind(this);
}
changeChildName(newName) {
this.setState({name: newName});
}
render() {
return (
<Child {...this.state} />
);
}
}
It seems a bit overkill to me that the Parent needs to re-render when the only thing that I want to re-render is the child view. How can I change the props of the <Child> component from the <Parent> component?
Secondary Questions
1) Is it possible to change the state of a component without having the component re-render?
2) Is there an onStateChange type event that we can tap into, or do we solely have componentWillReceiveProps?
1) Is it possible to change the state of a component without having the component re-render?
No, and it makes very little sense.
2) Is there an onStateChange type event that we can tap into, or do we solely have componentWillReceiveProps?
There is no, use componentWillReceiveProps.
It seems a bit overkill to me that the Parent needs to re-render when the only thing that I want to re-render is the child view.
Actually this is where you trick yourself: the parent IS changed, since what it returns is changed. The whole tree is being re-rendered from the root.
I think you misunderstand. It is very simple for a parent to change the child props... Just change the props that get rendered. Now, what if we want to do some changes in child without rerendering the parent. This is also pretty simple.
Attach a ref to your child and work with it. Now, the child cannot change its own props, so anything you mess with within the child will not be a prop. Props are passed down from the parent every time the parent rerenders.
So,
class Parent extends Component {
constructor(props) {
super(props);
this.childProps = {name:'name',age:12,type:'child'};
}
doSomethingOnChild() {
this.refs.child.callFunctionOfChildThatWillMessWithItself();
}
render() {
return (
<Child {...this.childProps} ref="child" />
);
}
}