0

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?

thisissami
  • 15,445
  • 16
  • 47
  • 74
  • for those of you downvoting this question, could you at the very least explain why you are doing so? Plenty of writing online says that this should be possible. – thisissami Nov 24 '16 at 02:14

2 Answers2

1

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.

zerkms
  • 249,484
  • 69
  • 436
  • 539
  • Ah ok this makes sense. – thisissami Nov 24 '16 at 02:14
  • Is the original question that I asked (AKA having a parent change a child prop) actually possible? if not, why do a lot of articles say that it is? – thisissami Nov 24 '16 at 02:15
  • @thisissami provide a link to some. – zerkms Nov 24 '16 at 02:15
  • https://developmentarc.gitbooks.io/react-indepth/content/life_cycle/growth_update_indepth.html (this isn't a parent changing a child, but the `Starting Update: Changing Props` section implies that props are changeable.) One sec looking through my browser history to see all that i've looked at today. – thisissami Nov 24 '16 at 02:18
  • @thisissami you can "change" properties of the element (not component) by re-rendering an element that hosts it. (that's what you don't like) – zerkms Nov 24 '16 at 02:21
  • things like this accepted answer on StackOverflow: http://stackoverflow.com/questions/24939623/can-i-update-a-components-props-in-react-js – thisissami Nov 24 '16 at 02:21
  • @thisissami yes, re-render the parent element with new child properties. – zerkms Nov 24 '16 at 02:22
  • so when somebody says `[you] can update its state and the props of its children.` - they're really saying `you can rerender`? – thisissami Nov 24 '16 at 02:22
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/128890/discussion-between-zerkms-and-thisissami). – zerkms Nov 24 '16 at 02:23
  • Ok thanks so much for clarifying. The vocabulary used in a lot of what I've read today has been really confusing to me. It's implied that `props of an existing rendered component can be changed`, not `the component will be re-rendered` – thisissami Nov 24 '16 at 02:24
0

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" />
    );
  }
}
David
  • 7,028
  • 10
  • 48
  • 95
  • ok so this is a workaround that doesn't use props at all, as i'm assuming that `this.refs.child.props.name = newName` won't work. – thisissami Nov 24 '16 at 02:30
  • While `this.refs.child.props.name` may actually change the prop, it is probably one of the largest anti-patterns in React and is working outside what React expects. Your parent will have false knowledge of the child, etc. I recommend finding a different approach. – David Nov 24 '16 at 02:33
  • cool - my chat with @zerkms above has clarified that I'm doing things correctly with the current state of my code (using `setState`) – thisissami Nov 24 '16 at 02:35