Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

"setState" on componentDidMount #4

Open
efflam opened this issue Jul 8, 2015 · 7 comments
Open

"setState" on componentDidMount #4

efflam opened this issue Jul 8, 2015 · 7 comments

Comments

@efflam
Copy link

efflam commented Jul 8, 2015

Hi
I'm trying to create a smart component to retrieve window size and pass it as props to the dumb component. It works fine when I resize the window.
I was wondering how i could update width and height on componentDidMount with this approach.

const TestContainer = createRxComponent(props$ => {

  const resize$ = Observable
    .fromEvent(window, 'resize')
    .map( e => ({ width: window.innerWidth, height: window.innerHeight }) )
    .startWith({ width: 0, height: 0 })

  return Observable.combineLatest(props$, resize$, (props, { width, height }) => ({
    ...props,
    width,
    height
  }))

}, Test)


function Test(props){
  const { width, height } = props
  return (
    <div>
      <p>width: {width}</p>
      <p>height: {height}</p>
    </div>
  )
} 
@acdlite
Copy link
Owner

acdlite commented Jul 8, 2015

props$ receives only a single value before mounting, from inside the constructor. After than it updates on componentWillReceiveProps(), which is only called after mounting.

$componentDidMount = $props
  .skip(1)
  .take(1);

// Or just
$propsAfterMount = $props.skip(1);

This is a good topic for the docs, thanks!

@acdlite acdlite closed this as completed Jul 8, 2015
@istarkov
Copy link

istarkov commented Jul 8, 2015

@acdlite But this $props.skip(1).take(1) is not componentDidMount, it's first componentWillReceiveProps call, which can never occurs.

There are situations (for example to detect size of component) where real componentDidMount is needed.

@efflam
Copy link
Author

efflam commented Jul 9, 2015

Thx @acdlite. I tried your suggestion with no success. TestContainer doesn't receive any props from his parent so componentWillReceiveProps is never called.

@acdlite acdlite reopened this Jul 9, 2015
@acdlite
Copy link
Owner

acdlite commented Jul 9, 2015

Ah I see what you mean. @istarkov @efflam Could you use a callback ref with a funcSubject() instead?

<div ref={() => componentDidMount$() }>

@acdlite
Copy link
Owner

acdlite commented Jul 9, 2015

@efflam So your example would look like:

const TestContainer = createRxComponent(props$ => {
 const containerRef$ = funcSubject()
 const resize$ = Observable
    .fromEvent(window, 'resize');

 const size$ = Observable.combineLatest(containerRef$, resize$,
    containerRef => React.findDOMNode(component))
    .map( el => ({ width: el.innerWidth, height: el.innerHeight }) )
    .startWith({ width: 0, height: 0 })

  return Observable.combineLatest(props$, size$, $containerRef, (props, { width, height }, containerRef) => ({
    ...props,
    containerRef
    width,
    height
  }))

}, Test)


function Test(props){
  const { width, height, containerRef } = props
  return (
    <div ref={containerRef}>
      <p>width: {width}</p>
      <p>height: {height}</p>
    </div>
  )
}

EDIT: fixed (I believe)

@acdlite
Copy link
Owner

acdlite commented Jul 9, 2015

^ Btw I don't think that will work until #5 is fixed. I'll look at it today and write a test case to confirm.

@miketembo
Copy link

so whats the best way to do it

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants