mikejw mikejw - 2 months ago 21
Javascript Question

window.innerHeight with React and redux

I asked a question recently (Simple window resize react) to get most of this solution working however now I am plugging in redux so that I can refactor out the web service call to an action creator and receive the data through a reducer. (The call is made using jsonp-promise and I am using the appropriate redux middleware.)

However now I can't seem to use window.innerHeight as it always returns 200 :/

Is the problem due to having some of state managed by redux and some of it native to the component (i.e. 'height')?

Many thanks in advance!

import React, { Component } from 'react';
import { connect } from 'react-redux';
import { bindActionCreators } from 'redux';
import GalleryItem from '../components/gallery_item';
import Nav from '../components/nav';
import { fetchImages } from '../actions/index';

export const MF = 'http://www.veilcraft.com';


class Gallery extends Component {


constructor(props) {
super(props);

this.state = {
images: [],
height: window.innerHeight
};

this.handleResize = this.handleResize.bind(this);
this.props.fetchImages();
}

componentDidMount() {
window.addEventListener('resize', this.handleResize);
}

handleResize(e) {

this.setState({
height: window.innerHeight
});
}

componentWillUnmount() {
window.removeEventListener('resize', this.handleResize);
}

render() {

console.log(this.props.height); //outputs 200!

const galleryItems = this.props.images.map((image) => {
return <GalleryItem key={image} image={image} height={this.props.height} />
});

return (
<div>
<Nav />
<section>
{galleryItems}
</section>
</div>
);
}
}

function mapStateToProps(state) {

return {
images: state.images
}
}


function mapDispatchToProps(dispatch) {
return bindActionCreators({ fetchImages }, dispatch);
}

export default connect(mapStateToProps, mapDispatchToProps)(Gallery);


The action:

import jsonp from 'jsonp-promise';
import { MF } from '../containers/gallery'


export const FETCH_IMAGES = 'FETCH_IMAGES';

export function fetchImages() {

const url = `${MF}/home/`
const request = jsonp(url, {}).promise;

return {
type: FETCH_IMAGES,
payload: request //return promise
};
}


The reducer:

import { FETCH_IMAGES } from '../actions/index'

export default function(state = [], action) {

switch(action.type) {
case FETCH_IMAGES:
var images = action.payload.data.images.images.data.map((image) => {
return image.image;
});

return [ ...images, ...state ];
}
return state;
}

Answer

In handleResize you're updating the state of your Gallery component. You then pass the height down into GalleryItem as a prop.

That means that, inside Gallery, you need to write

console.log(this.state.height);

While inside GalleryItem you can write:

console.log(this.props.height);
Comments