eiriklv / react-masonry-component Goto Github PK
View Code? Open in Web Editor NEWA React.js component for using @desandro's Masonry
License: MIT License
A React.js component for using @desandro's Masonry
License: MIT License
Hi. Is anyone know how to detect broken image? not anyBroken, i want to check each image on load for know is it loaded, broken, and create some placeholder for image, and then when image is loaded === true, change placeholder to loaded image or to broken placeholder.
Would you consider including a TypeScript definition file in the package?
http://www.typescriptlang.org/docs/handbook/typings-for-npm-packages.html
I have 12 objects in my Masonry container. Upon changing one of the objects, the entire masonry component must update.
However I'm seeing quite a significant jank as a result. When I use an ordinary container instead of a Masonry container the jank does not occur.
Any reasons why? In my 12 objects I return false in shouldComponentUpdate for 11 of them so I know only 1 rerenders, and the masonry rerenders, but I don't understand the jank that Masony is causing.
Any suggestions what may be the cause?
In the example, you have class name open to customization, would it be possible also to provide those styles as an optional dependency?
... // image
<li className="image-element-class">
.... // gallery
className={'my-gallery-class'} // default ''
I am using bootstrap's thumbnail component, and it is not working for me at all. The functionalities are working, but the styling looks off. For example, there are no padding between each child elements.
var React = require('react');
var Masonry = require('react-masonry-component')(React);
var elements = [{src: "http://placehold.it/350x150"}, {
src: "http://placehold.it/350x150"
}, {src: "http://placehold.it/350x150"}, {src: "http://placehold.it/350x150"}, {src: "http://placehold.it/350x150"}];
var masonryOptions = {
transitionDuration: 0
};
var Gallery = React.createClass({
render: function () {
var childElements = this.props.elements.map(function (element) {
return (
<div className="col-xs-6 col-md-4 col-lg-3">
<a href="#" className="thumbnail">
<img src={element.src} alt="example"/>
</a>
</div>
);
});
return (
<Masonry
className={'row'} // default ''
elementType={'div'} // default 'div'
options={masonryOptions} // default {}
disableImagesLoaded={false} // default false
>
{childElements}
</Masonry>
);
}
});
module.exports = Gallery;
Has anyone got this working in safari? I have it working in chrome and firefox, but safari crashes
Is there any way to prevent masonry from re-ordering elements? I don't need the "optimal" placement of elements as the order of my elements is important. All I want is for 2 elements in the same column to have no whitespace between them.
I have an array with elements that I get from filtering a larger array base on some value. I give the children to the masonry unique keys. This works great when the visible child at position 0 in array remains visible all the time. But when a child gets prepended in the array the child elements start to overlap.
class CategoryPage extends React.Component {
static propTypes = {
category: PropTypes.string.isRequired,
}
getCategory = () => {
const { category } = this.props;
return categories
.filter((cat) => {
return cat.params.category === category;
})[0];
}
render() {
const { items } = this.props;
const options = {
gutter: 0,
isFitWidth: true
}
const current = this.getCategory();
const filtered = items
.filter(item => {
return item.categories.some((category) => {
return current.tags.indexOf(category) !== -1;
});
})
.map(item => {
return (
<Card
key={item.id}
id={item.id}
title={item.title}
image={item.image}
description={item.description}
categories={item.categories} />
);
});
return (
<div>
<div className="background-transition" style={{'background': current.color, 'padding': '20px 0'}}>
<div className="container align-center">
<h2>{ current.text }</h2>
</div>
</div>
<div className="container align-center">
<Masonry
options={options}
disableImagesLoaded={true} >
{filtered}
</Masonry>
</div>
</div>
);
}
}
export default CategoryPage;
HI @eiriklv, thanks for the great project. 👍 I have a general question. I need to extend your work to add infinite scrolling. My plan is to fork your work and make my sub-project available to others. I'm pretty new to React and Masonry, so i was wondering if you had any thoughts on how you would solve this problem? Furthermore, are there any infinite scrolling libs that you know of which would be a good fit for integrating with your work? thanks
Hi Eirik, thanks for building this. When using with React 0.14 RC1:
If using React.render()
, the app works fine, but I get:
Warning: React.render is deprecated. Please use ReactDOM.render from require('react-dom') instead.
Warning: React.findDOMNode is deprecated. Please use ReactDOM.findDOMNode from require('react-dom') instead.
If importing ReactDOM and using ReactDOM.render()
, the app does not work, I get:
Uncaught (in promise) Error: Invariant Violation: addComponentAsRefTo(...): Only a ReactOwner can have refs. You might be adding a ref to a component that was not created inside a component's `render` method, or you have multiple copies of React loaded (details: https://fb.me/react-refs-must-have-owner).
How do you tell the grid elements to pack center instead of left?
Would be really useful if the original source for the hearsay.me live demo was somehow included here.
The React-Masonry-Component does not update if a child component changes size - it causing overlapping issues/general ugliness.
There should be a way to monitor children component for size changes.
For example in this scenario. If ChildOne's state is updated it will be re-rendered but the Masonry component would not be and therefore not realigned properly (unless it was listening for the same changes - which is not always practical).
<Masonry options={options}>
<ChildOne />
<ChildTwo />
</Masonry
Am I doing something wrong or is this an actual bug/not fixable?
Cheers!
might be the same issue as #2
I don't know how to filter my selectItem? Is Masonry have support filter function like Isotope ?
Hi, I've been struggling to make the events work with typescript. I followed the example you gave but it just never fires. Maybe I'm doing something wrong, i don't know, I'm quite new to react and typescript/es6. Would be cool if you could provide a complete example!
Here's a small portion of the code
Thanks
var Masonry = require('react-masonry-component');
public handleImagesLoaded(imagesLoadedInstance) {
this.setState({
showImages: true
});
}
public render() {
let masonryOptions = {
transitionDuration: 0
};
let posts = this.state.showImages ? this.state.posts.map((post, i) => {
return <PostComponentReact key={i} post={post}></PostComponentReact>
}) : null;
return (
<section id="content">
<div className="page pl-25 pr-25 mb-40">
<Masonry className="row"
ref="masonry"
options={masonryOptions}
onImagesLoaded={this.handleImagesLoaded}
>
{posts}
</Masonry>
</div>
</section>
)
}
Hi I have a use case that's giving some problems.
I'm putting children inside a div container with a certain height, and has overflow:auto
The component works fine, but when I change the children list to a shorter size, and upon rerender, the container div height would not shrink. It would take 2 state changes for the container div to shrink properly.
Any idea why this is? Thanks
In my React application I've set a timer that polls for new posts from a certan API. Whenever a new post is fetched, the component that holds the Masonry component receives the updated array of posts causing the render()
method to trigger. This causes the whole grid to be re-rendered (all the items do the animation, instead of just the new ones).
In the old project I used to do that the masonry docs says:
$grid.prepend( $items )
// add and lay out newly prepended items
.masonry( 'prepended', $items );
How to achieve such behavior with react
and react-masonry-component
?
I'm new to React so maybe this is not related specifically to your component. I'm sorry if that's the case.
I get this error when trying to include the masonry component:
TypeError: Cannot read property 'bool' of undefined
at new MasonryComponent (/Users/pvijeh/projects/sull-isom/node_modules/react-masonry-component/lib/index.js:15:49)
at [object Object].ReactCompositeComponentMixin.mountComponent (/Users/pvijeh/projects/sull-isom/node_modules/react/lib/ReactCompositeComponent.js:148:18)
at [object Object].wrapper as mountComponent
at Object.ReactReconciler.mountComponent (/Users/pvijeh/projects/sull-isom/node_modules/react/lib/ReactReconciler.js:37:35)
at [object Object].ReactCompositeComponentMixin.mountComponent (/Users/pvijeh/projects/sull-isom/node_modules/react/lib/ReactCompositeComponent.js:225:34)
at [object Object].wrapper as mountComponent
at Object.ReactReconciler.mountComponent (/Users/pvijeh/projects/sull-isom/node_modules/react/lib/ReactReconciler.js:37:35)
at [object Object].ReactCompositeComponentMixin.mountComponent (/Users/pvijeh/projects/sull-isom/node_modules/react/lib/ReactCompositeComponent.js:225:34)
at [object Object].wrapper as mountComponent
at Object.ReactReconciler.mountComponent (/Users/pvijeh/projects/sull-isom/node_modules/react/lib/ReactReconciler.js:37:35)
at ReactDOMComponent.ReactMultiChild.Mixin.mountChildren (/Users/pvijeh/projects/sull-isom/node_modules/react/lib/ReactMultiChild.js:241:44)
at ReactDOMComponent.Mixin._createContentMarkup (/Users/pvijeh/projects/sull-isom/node_modules/react/lib/ReactDOMComponent.js:591:32)
at ReactDOMComponent.Mixin.mountComponent (/Users/pvijeh/projects/sull-isom/node_modules/react/lib/ReactDOMComponent.js:479:29)
at Object.ReactReconciler.mountComponent (/Users/pvijeh/projects/sull-isom/node_modules/react/lib/ReactReconciler.js:37:35)
at [object Object].ReactCompositeComponentMixin.mountComponent (/Users/pvijeh/projects/sull-isom/node_modules/react/lib/ReactCompositeComponent.js:225:34)
at [object Object].wrapper as mountComponent
////////////////////////////////////////////////////////////////////////////////////////////////////////////////
Here is my webpack config file:
////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/**
import path from 'path';
import webpack from 'webpack';
import merge from 'lodash.merge';
const DEBUG = !process.argv.includes('--release');
const VERBOSE = process.argv.includes('--verbose');
const WATCH = global.WATCH === undefined ? false : global.WATCH;
const AUTOPREFIXER_BROWSERS = [
'Android 2.3',
'Android >= 4',
'Chrome >= 35',
'Firefox >= 31',
'Explorer >= 9',
'iOS >= 7',
'Opera >= 12',
'Safari >= 7.1',
];
const GLOBALS = {
'process.env.NODE_ENV': DEBUG ? '"development"' : '"production"',
DEV: DEBUG,
};
//
// Common configuration chunk to be used for both
// client-side (app.js) and server-side (server.js) bundles
// -----------------------------------------------------------------------------
const config = {
output: {
publicPath: '/',
sourcePrefix: ' ',
},
cache: DEBUG,
debug: DEBUG,
stats: {
colors: true,
reasons: DEBUG,
hash: VERBOSE,
version: VERBOSE,
timings: true,
chunks: VERBOSE,
chunkModules: VERBOSE,
cached: VERBOSE,
cachedAssets: VERBOSE,
},
plugins: [
new webpack.optimize.OccurenceOrderPlugin(),
],
resolve: {
extensions: ['', '.webpack.js', '.web.js', '.js', '.jsx', '.json'],
},
module: {
loaders: [
{
test: /.jsx?$/,
include: [
path.resolve(__dirname, '../node_modules/react-routing/src'),
path.resolve(__dirname, '../src'),
],
loader: 'babel-loader',
}, {
test: /.json$/,
loader: 'json-loader',
}, {
test: /.txt$/,
loader: 'raw-loader',
}, {
test: /.(png|jpg|jpeg|gif|svg|woff|woff2)$/,
loader: 'url-loader?limit=10000',
}, {
test: /.(eot|ttf|wav|mp3)$/,
loader: 'file-loader',
}, {
test: /.scss$/,
loader: 'style-loader/useable!css-loader!postcss-loader',
}, {
test: /.jsx?$/,
exclude: /node_modules/,
loader: 'babel'
},
{
test: /masonry|imagesloaded|fizzy-ui-utils|desandro-|outlayer|get-size|doc-ready|eventie|eventemitter/,
loader: 'imports?define=>false&this=>window'
}
],
},
postcss: function plugins(bundler) {
return [
require('postcss-import')({ addDependencyTo: bundler }),
require('precss')(),
require('autoprefixer')({ browsers: AUTOPREFIXER_BROWSERS }),
require('css-mqpacker')(),
require('csswring')()
// require('cssnano')({discardComments: {removeAll: true}})
];
},
};
//
// Configuration for the client-side bundle (app.js)
// -----------------------------------------------------------------------------
const appConfig = merge({}, config, {
entry: [
...(WATCH ? ['webpack-hot-middleware/client'] : []),
'./src/app.js',
],
output: {
path: path.join(__dirname, '../build/public'),
filename: 'app.js',
},
// Choose a developer tool to enhance debugging
// http://webpack.github.io/docs/configuration.html#devtool
devtool: DEBUG ? 'cheap-module-eval-source-map' : false,
plugins: [
new webpack.DefinePlugin(GLOBALS),
...(!DEBUG ? [
new webpack.optimize.DedupePlugin(),
new webpack.optimize.UglifyJsPlugin({
compress: {
warnings: VERBOSE,
},
}),
new webpack.optimize.AggressiveMergingPlugin(),
] : []),
...(WATCH ? [
new webpack.HotModuleReplacementPlugin(),
new webpack.NoErrorsPlugin(),
] : []),
],
});
// Enable React Transform in the "watch" mode
appConfig.module.loaders
.filter(x => WATCH && x.loader === 'babel-loader')
.forEach(x => x.query = {
// Wraps all React components into arbitrary transforms
// https://github.com/gaearon/babel-plugin-react-transform
plugins: ['react-transform'],
extra: {
'react-transform': {
transforms: [
{
transform: 'react-transform-hmr',
imports: ['react'],
locals: ['module'],
}, {
transform: 'react-transform-catch-errors',
imports: ['react', 'redbox-react'],
},
],
},
},
});
//
// Configuration for the server-side bundle (server.js)
// -----------------------------------------------------------------------------
const serverConfig = merge({}, config, {
entry: './src/server.js',
output: {
path: './build',
filename: 'server.js',
libraryTarget: 'commonjs2',
},
target: 'node',
externals: [
function filter(context, request, cb) {
const isExternal =
request.match(/^[@a-z][a-z/.-0-9]*$/i) &&
!request.match(/^react-routing/) &&
!context.match(/[/]react-routing/);
cb(null, Boolean(isExternal));
},
],
node: {
console: false,
global: false,
process: false,
Buffer: false,
__filename: false,
__dirname: false,
},
devtool: 'source-map',
plugins: [
new webpack.DefinePlugin(GLOBALS),
new webpack.BannerPlugin('require("source-map-support").install();',
{ raw: true, entryOnly: false }),
],
});
// Remove style-loader
from the server-side bundle configuration
serverConfig.module.loaders
.filter(x => x.loader.startsWith('style-loader/useable!'))
.forEach(x => x.loader = x.loader.substr(21));
export default [appConfig, serverConfig];
////////////////////////////////////////////////////////////////////////////////////////////////////////////////
Here is my package.json file:
////////////////////////////////////////////////////////////////////////////////////////////////////////////////
{
"private": true,
"engines": {
"node": ">=4.1 <5",
"npm": ">=3.1 <4"
},
"dependencies": {
"babel-core": "5.8.33",
"bluebird": "3.0.5",
"classnames": "2.2.0",
"eventemitter3": "1.1.1",
"exenv": "^1.2.0",
"express": "4.13.3",
"fastclick": "1.0.6",
"fbjs": "0.4.0",
"flux": "2.1.1",
"front-matter": "2.0.0",
"history": "1.13.1",
"imports-loader": "^0.6.5",
"jade": "1.11.0",
"jquery": "^2.1.4",
"lodash": "^3.10.1",
"normalize.css": "3.0.3",
"object-assign": "^4.0.1",
"postcss-mixins": "^3.0.2",
"react": "0.14.2",
"react-dom": "0.14.2",
"react-routing": "0.0.5",
"source-map-support": "0.3.3",
"superagent": "1.4.0"
},
"devDependencies": {
"autoprefixer": "^6.1.0",
"babel": "^5.8.34",
"babel-eslint": "^4.1.4",
"babel-loader": "^5.3.3",
"babel-plugin-react-transform": "^1.1.1",
"browser-sync": "^2.9.12",
"css-loader": "^0.23.0",
"css-mqpacker": "^4.0.0",
"csscomb": "^3.1.8",
"csswring": "^4.0.0",
"del": "^2.0.2",
"eslint": "^1.8.0",
"eslint-config-airbnb": "1.0.0",
"eslint-loader": "^1.1.1",
"eslint-plugin-react": "^3.7.1",
"file-loader": "^0.8.4",
"gaze": "^0.5.2",
"git-repository": "^0.1.1",
"glob": "^6.0.1",
"jest-cli": "^0.7.1",
"jscs": "^2.5.0",
"lodash.merge": "^3.3.2",
"mkdirp": "^0.5.1",
"ncp": "^2.0.0",
"postcss": "^5.0.10",
"postcss-import": "^7.1.3",
"postcss-loader": "^0.8.0",
"precss": "^1.3.0",
"react-transform-catch-errors": "^1.0.0",
"react-transform-hmr": "^1.0.1",
"redbox-react": "^1.1.1",
"replace": "^0.3.0",
"style-loader": "^0.13.0",
"url-loader": "^0.5.6",
"webpack": "^1.12.3",
"webpack-dev-middleware": "^1.2.0",
"webpack-hot-middleware": "^2.5.0"
},
"jest": {
"rootDir": "./src",
"scriptPreprocessor": "../preprocessor.js",
"unmockedModulePathPatterns": [
"fbjs",
"react"
]
},
"scripts": {
"lint": "eslint src tools && jscs src tools",
"csslint": "csscomb src/components --lint --verbose",
"csscomb": "csscomb src/components --verbose",
"test": "eslint src && jest",
"clean": "babel-node tools/run clean",
"copy": "babel-node tools/run copy",
"bundle": "babel-node tools/run bundle",
"build": "babel-node tools/run build",
"deploy": "babel-node tools/run deploy",
"serve": "babel-node tools/run serve",
"start": "babel-node tools/run start"
}
I'd like to change the state of my app once the masonry layout is complete but that requires binding to the event listener "layoutComplete". Does this component provide an instance to the masonry object for event binding?
Hello,
I try to implement your react component in a project but the margin left is all the time equal to 0.
My React compoment :
import React from 'react';
import ReactDOM from 'react-dom';
import Masonry from 'react-masonry-component';
import { default as Video, Controls, Play, Mute, Seek, Fullscreen, Time, Overlay } from 'react-html5video';
var masonryOptions = {
itemSelector: '.grid-item',
columnWidth: '.grid-sizer',
gutter: 10,
isOriginLeft: true
};
export class Gallery extends React.Component {
constructor()
{
super();
this.state = {
elements: []
};
};
componentDidMount()
{
$.ajax({
url: this.props.url,
dataType: 'json',
cache: false,
success: function(data) {
this.setState({
elements: data.contents
});
}.bind(this),
error: function(xhr, status, err) {
alert("Erreur lors de la requête code : " + status + err.toString());
}.bind(this)
});
};
render()
{
var childElements = this.state.elements.map(function(element, index) {
if(element.type === 'images') {
return (
<li className='grid-item'>
<img src={element.src} />
</li>
);
}
if(element.type === 'video') {
return(
<li className='grid-item'>
<Video controls
poster="https://www.google.com/url?sa=i&rct=j&q=&esrc=s&source=images&cd=&cad=rja&uact=8&ved=0ahUKEwjP54jK4IHOAhUE1RoKHXpABMwQjRwIBw&url=http%3A%2F%2Fwww.izoa.fr%2Fpapier-peint-deco-paysage%2F2729-poster-mural-design-tokyo-by-night.html&bvm=bv.127521224,d.d2s&psig=AFQjCNHVqrk-6MpdtGRLCJCsI4AMZOhrug&ust=1469094218037889"
onCanPlayThrough={() => {
}}>
<source src={element.src} type="video/mp4" />
</Video>
</li>
);
}
});
return (
<Masonry
className={'grid'} // default ''
elementType={'gridMasonry'} // default 'div'
options={masonryOptions} // default {}
disableImagesLoaded={false} // default false
updateOnEachImageLoad={false} // default false and works only if disableImagesLoaded is false
>
<div className="grid-sizer"></div>
{childElements}
</Masonry>
);
};
}
My html file :
<!doctype html>
<html>
<head>
<link rel="stylesheet" type="text/css" href="src/css/style.css">
</head>
<body>
<h1> Test React Masonry </h1>
<div id="gridMasonry">
</div>
</body>
<script src="https://code.jquery.com/jquery-2.2.0.min.js"></script>
<script type="text/javascript" src="bundle.js"> </script>
<script type="text/javascript" src="node_modules/bootstrap/dist/js/bootstrap.min.js"></script>
</html>
The css :
/* ---- grid ---- */
.grid {
max-width: 100%;
padding: 0;
}
/* ---- grid-item ---- */
.grid-sizer{
width: calc(33% - 5px);
}
.grid-item {
float: left;
}
#gridMasonry {
height: 600px;
width: 700px;
}
The main js
import {Gallery} from './gallery.jsx';
import ReactDOM from 'react-dom';
import React from 'react';
ReactDOM.render(<Gallery url="http://localhost/projetReactMasonry/json.php"/>, document.getElementById('gridMasonry'));
Have you got any ideas for this problem ?
The objective is to render images/movies from a json call with a path.
Thank you for future answer,
Julien
handleImagesLoaded triggers multiple times,
I am using:
onLayoutComplete={handleImagesLoaded}
with function inside the createClass
onLayoutComplete={this.handleImagesLoaded}
it triggers 2 times , otherwise its 4 or 5
I'm no expert and understand that raising this as an issue may not be the correct thing to do, I just cannot get it to work.
The plugin works fine in my dev build process but when trying to compile for production i'm getting this error.
ERROR in bundle.js from UglifyJs
SyntaxError: Unexpected token: name (forceItemReload) [./~/react-masonry-component/lib/index.js:68,0]
The error is coming from UglifyJs so could it be something to do with my webpack config? see below for the uglify plugin configuration that i've been using to minify react.
new webpack.optimize.UglifyJsPlugin({
compress: {
screw_ie8: true
}
})
I can't figure out what I'm doing wrong. My code below is almost identical to the example given, but I'm trying to style the child elements of the Masonry component. The problem is that transitions don't work with the current styling. If I remove the "height" property and only use "width", transitions do work! Can anyone help? (I'm using the latest Chrome browser.)
import React from 'react';
var Masonry = require('react-masonry-component')(React);
var masonryOptions = {
transitionDuration: '0.6s',
columnWidth: 200
};
class Container extends React.Component {
render() {
let style = { width: 180, height: 180 }; //**** styling seems to cause trouble
let urls = ["../img/worksheet.jpg", "../img/activity.jpg"];
let childElements = urls.map((url,idx)=>{
return <img key={idx} style={style} src={url} />;
});
return (
<Masonry
className={''} // default ''
elementType={'div'} // default 'div'
options={masonryOptions} // default {}
disableImagesLoaded={false} // default false
>
{childElements}
</Masonry>
)
}
}
export default Container;
Sometimes the masonry layout seems to work when my data is loaded from the server. But sometimes it's just messed. Tried to debug it and couldn't find it.
Can someone help me with this?
I don't know if this is related to this #54
Its live here http://bindi.surge.sh/
It seems that there are issues using this with Meteor. Need to solve the pain points and update component/readme
Some of the dependencies listed in package.json
, including react
and react-dom
, will cause conflict and error when the project using your module is a plugin of a host project. See https://nodejs.org/en/blog/npm/peer-dependencies/
Could you move them into peerDependencies
?
With
import * as Masonry from 'react-masonry-component';
I get
ERROR in /media/website/js/node_modules/react-masonry-component/typings.d.ts
(5,22): error TS2665: Module augmentation cannot introduce new names in the top level scope.
ERROR in /media/website/js/node_modules/react-masonry-component/typings.d.ts
(20,15): error TS2665: Module augmentation cannot introduce new names in the top level scope.
ERROR in /media/website/js/node_modules/react-masonry-component/typings.d.ts
(29,26): error TS2665: Module augmentation cannot introduce new names in the top level scope.
"typescript": "^1.8.10"
"react-masonry-component": "^4.2.0"
EDIT: I see this could be a duplicate of #42
Hi, I'm instantiating Masonry pretty similarly to how you have it in the example, except each child element is a React component. For some reason, the dependent library outlayer throws an error "Bad masonry element". After that, it repeatedly has a "Can't read property children of undefined" error. Not sure what's going wrong here.
For some more context, I'm using React as the front-end with Meteor as the back-end. Thoughts about where this could be coming from?
Hi
I'm calculating the container and divs width and height before rendering masonry, but they only arrange correctly on a state change. Initially they're arranged stacked on top of eachother.
Is there any reason for this? Not sure if the fault lies with how I'm using React or Masonry atm.
I am adding/hiding elements within my component in response to a filter bar (kinda like what Isotope does). Everything works beautifully with animation, except removal of elements at the top of the Masonry layout:
When I have items 1-20 in the Masonry component, and then remove items 1-10, it leaves items 11-20. Unfortunately, instead of laying these out appropriately, it renders them all on the left side of the page (ie, they all have left: 0px
).
When I dig into the react-masonry-component code, diffDomChildren
seems to work correctly and return proper dictionaries, except when elements are removed. When these elements are removed, diffDomChildren
returns:
{
appended: [],
moved: [],
new: [10 elements],
old: [10 elements],
prepended: [],
removed: []
}
(I believe it should be returning 20 'old' elements, with 10 'removed'.)
If I change:
var oldChildren = this.domChildren.filter(function(element) {
/*
* take only elements attached to DOM
* (aka the parent is the masonry container, not null)
*/
return !!element.parentNode;
});
to:
var oldChildren = this.domChildren;
...then things work beautifully again. I'm confused why my change works, as it obviously seems to be intentionally written the way you've written it. When componentDidUpdate
is called, it seems the DOM elements have already been removed from the DOM and had their parentNode
null-ed.
I see this behavior with both React 15.1.0 and React 15.4.1 (along with react-masonry-component 4.4.0 and masonry-layout 4.1.1.)
Hi folks!
I noticed that Masonry 4.x is out, and it seems to me that it cuts file size pretty heavily by not requiring jQuery (don't quote me on that at all...) Is work being done to upgrade? I can possibly help, though I'm not familiar at all with the code base yet.
@eiriklv Firstly what do you think about adding Travis CI support in order to run tests on commit/pull request?
Second, you will have to do it, the repo is under your account.
(We could also create an org for this, but that might be overkill)
I am displaying my masonry tiles from a filtered array.
var myFilteredArray = myArray.filter( (tile) => this.props.filter.indexOf(tile.tag) > -1 )
var tiles = myFilteredArray.map( (tile) => <MyTile/>)
Where myArray
is an array of json objects with a tag field. props.filter
is an array of strings.
For exampleprops.filter
= ["a","b","c"] and the json tags are "a", "b", "c"
When I update my props filter so that props.filter = ["b"]
I see that the A and C objects disappear and object B moves to the left most of the container.
However when I add back tags "a" and "c" into props.filter, the objects show up in the wrong position.
I would expect that the objects be in the order A,B,C, and filling up the container from the left most. What I see however is that object B goes back to where it was originally, and A, and C show up either on top of it or to the right of is. That means there is a big empty space to the left of Object B
My question is why is this happening? And how do I fix this?
I am trying to handle the call of .layout() myself and looking at masonry's docs one can disable the layout by setting initLayout to false.
However this component doesn't use this option to disable the following lines that trigger layout:
componentWillReceiveProps: function() {
this._timer = setTimeout(function() {
this.masonry.reloadItems();
this.isMounted && this.isMounted() && this.forceUpdate();
}.bind(this), 0);
},
componentDidUpdate: function() {
this.performLayout();
this.imagesLoaded();
},
Are the Usage with webpack
instructions in the README still applicable. I use webpack, I didn't install/configure the imports-loader
and everything works fine. To the contrary... if I install and configure the imports-loader
per the instructions webpack stops working. I'm asking in case I'm overlooking something important.
Since react v15.2.0, you will get a warning when you pass a prop, that is not in the proptypes, to a DOM node.
Example:
<Masonry
ref="masonry"
className={'grid'}
elementType={'ul'}
options={masonryOptions}
disableImagesLoaded={false}>
{/* Other code */}
</Masonry>
Gives the following warnings:
Warning: Unknown props elementType
, options
, disableImagesLoaded
on ul tag. Remove these props from the element. For details, see https://fb.me/react-unknown-prop
Hi guys,
Having an issue with Masonry Component's parameter "disableImagesLoaded". It throws this error:
Uncaught TypeError: Cannot read property 'bool' of undefined
I've tried parsing false and creating a variable with false, but doesn't seem to work.
Is anyone else having issues with this?
The
componentWillReceiveProps: function() {
this._timer = setTimeout(function() {
this.masonry.reloadItems();
this.isMounted && this.isMounted() && this.forceUpdate();
}.bind(this), 0);
},
Is this block really needed as it seems to cause everything to run twice and it seems that I get some minor animation transition problems.
I've been trying to get a hold of masonry instance after render()
by passing masonry via refs
like so..
class List extends Component {
componentDidMount() {
if (this.masonry) {
console.log(this.masonry); // undefined
}
else{
console.log(this); // can see masonry as a SubClass instance
}
}
render() {
const listItems = [items];
return (<Masonry
ref={c => this.masonry = c.masonry}
className={'my-grid-class'}
elementType={'ul'}
options={masonryOptions}
disableImagesLoaded={false}
updateOnEachImageLoad={false}
>
{listItems}
</Masonry>);
}
}
Not sure what I'm missing here. Would be awesome if you can get a chance to help out.
/cc @eiriklv
Upgrading from 4.2.1
to 4.3.0
and getting the below exception. In my case, enableResizableChildren
is false
so initializeResizableChildren
returns without setting this. erd
. When destroyErd
is called (from componentWillUnmount
) it unconditionally references this.erd
resulting in the following error. This is a result of PR #55. All is fine with 4.2.1
TypeError: Cannot read property 'uninstall' of undefined
at Constructor.destroyErd (index.js:200)
at Constructor.componentWillUnmount (index.js:215)
at ReactCompositeComponent.js:408
at measureLifeCyclePerf (ReactCompositeComponent.js:74)
at ReactCompositeComponentWrapper.unmountComponent (ReactCompositeComponent.js:407)
at Object.unmountComponent (ReactReconciler.js:80)
at ReactCompositeComponentWrapper._updateRenderedComponent (ReactCompositeComponent.js:754)
at ReactCompositeComponentWrapper._performComponentUpdate (ReactCompositeComponent.js:721)
at ReactCompositeComponentWrapper.updateComponent (ReactCompositeComponent.js:642)
at ReactCompositeComponentWrapper.receiveComponent (ReactCompositeComponent.js:544)
Wondering why this library and most (all?) the libraries it depends on are pulling in Github dependencies?
They currently don't support semver versioning, and this leads to unpredictable results.
For instance this change from 2 days ago in a downstream dependency broke react-masonry-component for us. We had to shrinkwrap to enforce version numbers from within git dependencies.
desandro/matches-selector@7582db4
What are the thoughts on moving dependencies over to npm?
Hello,
I was expecting to use this component like this:
<Gallery>
<img src="" / >
<img src="" / >
<img src="" / >
<img src="" / >
</Gallery>
And I'm getting this error
TypeError: Cannot read property 'map' of undefined
at Constructor.render (/Users/ricardorauch/Sites/rickyrauch.me/.next/dist/components/gallery.js:21:48)
at /Users/ricardorauch/Sites/rickyrauch.me/node_modules/react/lib/ReactCompositeComponent.js:793:21
at measureLifeCyclePerf (/Users/ricardorauch/Sites/rickyrauch.me/node_modules/react/lib/ReactCompositeComponent.js:74:12)
Hi,
Thanks for this component! I'm having a slight issue when navigating away from pages using this component, with the console giving me the following warning:
Warning: forceUpdate(...): Can only update a mounted or mounting component. This usually means you called forceUpdate() on an unmounted component. This is a no-op.
You get this error when you load this component now.
Uncaught TypeError: elem[matchesMethod] is not a function
I think its because https://github.com/desandro/matches-selector got updated to v2.0.0
Is it possible to avoid reordering when more items get added?
current behaviour http://www.hearsay.me/
the desidered behaviour is this http://pintevent.com/
return {
old: knownChildrenStillAttached, // Not used
new: currentDomChildren, // Not used
removed: removed,
appended: appended,
prepended: prepended,
moved: moved,
//forceItemReload <- this code occur error on IE (message : ' : ' is required)
forceItemReload:forceItemReload
};
Updated React today to be greeted with this warning in the console. Haven't changed anything from my masonry component, still trying to figure out exactly how to prevent it. Only Masonry triggering this warning. My code is standard from README.md.
Linked: https://fb.me/react-unknown-prop
Hi, Just wanted to ask if there is a way to use virtual rendering to be able to render a big number of items and implement infinite scrolling...
I use this Masonry component to render "cards" that each contains a small image gallery. it renders great with a small number of items, but with a few hundreds it gets clunky...
is there a virtual rendering at all to ensure only the part of the least being rendered is the part that consumes memory while all the rest is free from it?
Cheers
Ajar
TypeScript 2.0.3 throws the following error on typings.d.ts
...\node_modules\react-masonry-component\typings.d.ts
(31,5): error TS2666: Exports and export assignments are not permitted in module augmentations.
I don't know why this is not allowed but I'll do some research on how to workaround this problem.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.