Code Monkey home page Code Monkey logo

Comments (12)

primetwig avatar primetwig commented on May 29, 2024

Nestable is a controlled component. Do you update items in your state?

from react-nestable.

jlei523 avatar jlei523 commented on May 29, 2024

Thanks for the reply.

I don't update items in my state. In fact, I don't even have items in my state at all. It's an object outside of the React class.

Note that running this.setState for any state, even states that have nothing to do with Nestable, will cause Nestable to not apply drag changes.

onDragChange(items, item) {
    this.setState({
      anyState: "any change"
    });
  }
      <Nestable
        collapsed
        items={items}
        renderItem={renderItem}
        handler={<span style={handlerStyles} />}
        ref={ref}
        onChange={(items, item) => this.onDragChange(items, item)}
      />

from react-nestable.

primetwig avatar primetwig commented on May 29, 2024

You have <Nestable items={items}. How exactly do you store items?
If you create it during every render, than updating the local state would create a new instance of items, which would be equal the initial shape of items.
Example: <Nestable items={items.slice(0)} will restore the initial items on every render of a parent component.
Try to check (on every render) if you accidentally update the link to your items. Make sure you pass the same instance for every render. Or update it in onChange.

from react-nestable.

jlei523 avatar jlei523 commented on May 29, 2024

You have <Nestable items={items}. How exactly do you store items?
If you create it during every render, than updating the local state would create a new instance of items, which would be equal the initial shape of items.
Example: <Nestable items={items.slice(0)} will restore the initial items on every render of a parent component.

Right now I'm just storing it in an object outside of the class. I have a function to convert that object into an object that works with Nestable.

import Nextable from "./nestable.jsx";
import { convertCostCentersIntoItems } from "./util";

let costCentersTest = {
  "1": "HEAD OFFICE",
  "2": "UK",
  "3": "INTERNATIONAL",
  "2-4": "UK > MANCHESTER",
  "2-5": "UK > LONDON",
  "2-5-7": "UK > LONDON > VAN-1",
  "2-5-7-9": "UK > LONDON > VAN-1 > DRIVER-1",
  "2-5-8": "UK > LONDON > VAN-2",
  "2-5-8-10": "UK > LONDON > VAN-2 > DRIVER-2",
  "2-6": "UK > BIRMINGHAM"
};

class CostCenters extends Component {
  constructor(props) {
    super(props);
    this.state = {
      needsSave: false,
      newCostCenterName: "",
      userChangedItems: []
    };

    this.onDragChange = this.onDragChange.bind(this);
  }

  async componentDidMount() {
    const response = await fetch(baseUrl + "/api/cost_centres_get");
    const data = await response.json();
    console.log(data);
    this.setState({
      items: convertCostCentersIntoItems(data)
    });
  }

  collapse = collapseCase => {
    if (this.refNestable) {
      switch (collapseCase) {
        case 0:
          this.refNestable.collapse("NONE");
          break;
        case 1:
          this.refNestable.collapse("ALL");
          break;
        case 2:
          this.refNestable.collapse([1]);
          break;
      }
    }
  };

  onDragChange(items, item) {}

  updateInputValue = event => {
    this.setState({
      newCostCenterName: event.target.value.toUpperCase()
    });
  };

  submitNewCostCenter = () => {
    let obj = {
      id: 10,
      text: this.state.newCostCenterName
    };

    this.setState({
      items: this.state.items.concat(obj)
    });
  };

  render() {
    return (
      <div>
        <Controls
          updateInputValue={this.updateInputValue}
          submit={this.submitNewCostCenter}
          cancel={this.hideNewCostCenterInput}
          collapse={this.collapse}
        />

        <Nextable
          items={convertCostCentersIntoItems(costCentersTest)}
          ref={el => (this.refNestable = el)}
          onChange={this.onDragChange}
        />
      </div>
    );
  }
}
import React from "react";
import Nestable from "react-nestable";
import EdiText from "react-editext";

const handlerStyles = {
  position: "absolute",
  top: 0,
  left: 0,
  width: "12px",
  height: "100%",
  background: "steelblue",
  cursor: "pointer"
};

const styles = {
  position: "relative",
  padding: "10px 15px",
  fontSize: "20px",
  border: "1px solid #f9fafa",
  background: "#f9fafa",
  cursor: "pointer",
  display: "flex"
};

const renderItem = ({ item, collapseIcon, handler }) => {
  return (
    <div style={styles}>
      {handler}
      {collapseIcon}
      <EdiText showButtonsOnHover value={item.text} onSave={() => {}} />
    </div>
  );
};

export default ({ items, ref, onChange }) => {
  return (
    <div>
      <Nestable
        collapsed
        items={items}
        renderItem={renderItem}
        handler={<span style={handlerStyles} />}
        ref={ref}
        onChange={(items, item) => onChange(items, item)}
      />
    </div>
  );
};

from react-nestable.

primetwig avatar primetwig commented on May 29, 2024

convertCostCentersIntoItems(costCentersTest) creates you a new instance of the Array every time component gets rerendered, which resets the internal state of Nestable.

from react-nestable.

jlei523 avatar jlei523 commented on May 29, 2024

convertCostCentersIntoItems(costCentersTest) creates you a new instance of the Array every time component gets rerendered, which resets the internal state of Nestable.

What's a way to fix this? Thanks!

from react-nestable.

primetwig avatar primetwig commented on May 29, 2024

Try to use memo pattern.
convertCostCentersIntoItems should (as an example) make a "shallow equal" check and return a new instance only when data was actually changed.

from react-nestable.

jlei523 avatar jlei523 commented on May 29, 2024

Try to use memo pattern.
convertCostCentersIntoItems should (as an example) make a "shallow equal" check and return a new instance only when data was actually changed.

If I use one of the example objects that doesn't need any formatting, it's still the same issue. IE. If I clone the example in the repo, add a this.setState to the onChange function, it'll still have the same issue.

Is there a pattern that you recommend without having to resort to using memo?

from react-nestable.

primetwig avatar primetwig commented on May 29, 2024

Check this part: https://github.com/primetwig/react-nestable/blob/master/src/Nestable/Nestable.js#L85
You have at least these 2 to be always new on every render:

handler={<span style={handlerStyles} />}
onChange={(items, item) => onChange(items, item)}

handler can be saved into top level variable.
onChange can be passed as is.

from react-nestable.

jlei523 avatar jlei523 commented on May 29, 2024

Check this part: https://github.com/primetwig/react-nestable/blob/master/src/Nestable/Nestable.js#L85
You have at least these 2 to be always new on every render:

handler={<span style={handlerStyles} />}
onChange={(items, item) => onChange(items, item)}

handler can be saved into top level variable.
onChange can be passed as is.

Ahh! The issue seemed to be handler. If I remove handler, it worked without changing anything else.

      <Nestable
        collapsed
        items={items}
        renderItem={renderItem}
        ref={ref}
        onChange={onChange}
      />

handler can be saved into top level variable.
Can you show me what you mean by this?

This caused the same rerender issue.

  const Handler = () => {
    return <span style={handlerStyles} />;
  };

      <Nestable
        collapsed
        items={items}
        renderItem={renderItem}
        handler={<Handler />}
        ref={ref}
        onChange={onChange}
      />

from react-nestable.

primetwig avatar primetwig commented on May 29, 2024
const handler = <span style={handlerStyles} />;
<Nestable handler={handler} />

from react-nestable.

jlei523 avatar jlei523 commented on May 29, 2024
const handler = <span style={handlerStyles} />;
<Nestable handler={handler} />

Worked! Thank you for your help!

from react-nestable.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.