Skip to content

Commit

Permalink
Look at impact of removing deprecated lifecycles (#4656)
Browse files Browse the repository at this point in the history
  • Loading branch information
JoviDeCroock committed Feb 18, 2025
1 parent ecf58fc commit 46d0e7a
Show file tree
Hide file tree
Showing 2 changed files with 0 additions and 277 deletions.
27 changes: 0 additions & 27 deletions compat/src/render.js
Original file line number Diff line number Diff line change
Expand Up @@ -40,33 +40,6 @@ const onChangeInputType = type => /fil|che|rad/.test(type);
// Some libraries like `react-virtualized` explicitly check for this.
Component.prototype.isReactComponent = {};

// `UNSAFE_*` lifecycle hooks
// Preact only ever invokes the unprefixed methods.
// Here we provide a base "fallback" implementation that calls any defined UNSAFE_ prefixed method.
// - If a component defines its own `componentDidMount()` (including via defineProperty), use that.
// - If a component defines `UNSAFE_componentDidMount()`, `componentDidMount` is the alias getter/setter.
// - If anything assigns to an `UNSAFE_*` property, the assignment is forwarded to the unprefixed property.
// See https://github.com/preactjs/preact/issues/1941
[
'componentWillMount',
'componentWillReceiveProps',
'componentWillUpdate'
].forEach(key => {
Object.defineProperty(Component.prototype, key, {
configurable: true,
get() {
return this['UNSAFE_' + key];
},
set(v) {
Object.defineProperty(this, key, {
configurable: true,
writable: true,
value: v
});
}
});
});

/**
* Proxy render() since React returns a Component reference.
* @param {import('./internal').VNode} vnode VNode tree to render
Expand Down
250 changes: 0 additions & 250 deletions compat/test/browser/component.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -75,254 +75,4 @@ describe('components', () => {
children: 'second'
});
});

describe('UNSAFE_* lifecycle methods', () => {
it('should support UNSAFE_componentWillMount', () => {
let spy = sinon.spy();

class Foo extends React.Component {
// eslint-disable-next-line camelcase
UNSAFE_componentWillMount() {
spy();
}

render() {
return <h1>foo</h1>;
}
}

React.render(<Foo />, scratch);

expect(spy).to.be.calledOnce;
});

it('should support UNSAFE_componentWillMount #2', () => {
let spy = sinon.spy();

class Foo extends React.Component {
render() {
return <h1>foo</h1>;
}
}

Object.defineProperty(Foo.prototype, 'UNSAFE_componentWillMount', {
value: spy
});

React.render(<Foo />, scratch);
expect(spy).to.be.calledOnce;
});

it('should support UNSAFE_componentWillReceiveProps', () => {
let spy = sinon.spy();

class Foo extends React.Component {
// eslint-disable-next-line camelcase
UNSAFE_componentWillReceiveProps() {
spy();
}

render() {
return <h1>foo</h1>;
}
}

React.render(<Foo />, scratch);
// Trigger an update
React.render(<Foo />, scratch);
expect(spy).to.be.calledOnce;
});

it('should support UNSAFE_componentWillReceiveProps #2', () => {
let spy = sinon.spy();

class Foo extends React.Component {
render() {
return <h1>foo</h1>;
}
}

Object.defineProperty(Foo.prototype, 'UNSAFE_componentWillReceiveProps', {
value: spy
});

React.render(<Foo />, scratch);
// Trigger an update
React.render(<Foo />, scratch);
expect(spy).to.be.calledOnce;
});

it('should support UNSAFE_componentWillUpdate', () => {
let spy = sinon.spy();

class Foo extends React.Component {
// eslint-disable-next-line camelcase
UNSAFE_componentWillUpdate() {
spy();
}

render() {
return <h1>foo</h1>;
}
}

React.render(<Foo />, scratch);
// Trigger an update
React.render(<Foo />, scratch);
expect(spy).to.be.calledOnce;
});

it('should support UNSAFE_componentWillUpdate #2', () => {
let spy = sinon.spy();

class Foo extends React.Component {
render() {
return <h1>foo</h1>;
}
}

Object.defineProperty(Foo.prototype, 'UNSAFE_componentWillUpdate', {
value: spy
});

React.render(<Foo />, scratch);
// Trigger an update
React.render(<Foo />, scratch);
expect(spy).to.be.calledOnce;
});

it('should alias UNSAFE_* method to non-prefixed variant', () => {
let inst;
class Foo extends React.Component {
// eslint-disable-next-line camelcase
UNSAFE_componentWillMount() {}
// eslint-disable-next-line camelcase
UNSAFE_componentWillReceiveProps() {}
// eslint-disable-next-line camelcase
UNSAFE_componentWillUpdate() {}
render() {
inst = this;
return <div>foo</div>;
}
}

React.render(<Foo />, scratch);

expect(inst.UNSAFE_componentWillMount).to.equal(inst.componentWillMount);
expect(inst.UNSAFE_componentWillReceiveProps).to.equal(
inst.UNSAFE_componentWillReceiveProps
);
expect(inst.UNSAFE_componentWillUpdate).to.equal(
inst.UNSAFE_componentWillUpdate
);
});

it('should call UNSAFE_* methods through Suspense with wrapper component #2525', () => {
class Page extends React.Component {
UNSAFE_componentWillMount() {}
render() {
return <h1>Example</h1>;
}
}

const Wrapper = () => <Page />;

sinon.spy(Page.prototype, 'UNSAFE_componentWillMount');

React.render(
<React.Suspense fallback={<div>fallback</div>}>
<Wrapper />
</React.Suspense>,
scratch
);

expect(scratch.innerHTML).to.equal('<h1>Example</h1>');
expect(Page.prototype.UNSAFE_componentWillMount).to.have.been.called;
});
});

describe('defaultProps', () => {
it('should apply default props on initial render', () => {
class WithDefaultProps extends Component {
constructor(props, context) {
super(props, context);
expect(props).to.be.deep.equal({
fieldA: 1,
fieldB: 2,
fieldC: 1,
fieldD: 2
});
}
render() {
return <div />;
}
}
WithDefaultProps.defaultProps = { fieldC: 1, fieldD: 1 };
React.render(
<WithDefaultProps fieldA={1} fieldB={2} fieldD={2} />,
scratch
);
});

it('should apply default props on rerender', () => {
let doRender;
class Outer extends Component {
constructor() {
super();
this.state = { i: 1 };
}
componentDidMount() {
doRender = () => this.setState({ i: 2 });
}
render(props, { i }) {
return <WithDefaultProps fieldA={1} fieldB={i} fieldD={i} />;
}
}
class WithDefaultProps extends Component {
constructor(props, context) {
super(props, context);
this.ctor(props, context);
}
ctor() {}
componentWillReceiveProps() {}
render() {
return <div />;
}
}
WithDefaultProps.defaultProps = { fieldC: 1, fieldD: 1 };

let proto = WithDefaultProps.prototype;
sinon.spy(proto, 'ctor');
sinon.spy(proto, 'componentWillReceiveProps');
sinon.spy(proto, 'render');

React.render(<Outer />, scratch);
doRender();

const PROPS1 = {
fieldA: 1,
fieldB: 1,
fieldC: 1,
fieldD: 1
};

const PROPS2 = {
fieldA: 1,
fieldB: 2,
fieldC: 1,
fieldD: 2
};

expect(proto.ctor).to.have.been.calledWithMatch(PROPS1);
expect(proto.render).to.have.been.calledWithMatch(PROPS1);

rerender();

// expect(proto.ctor).to.have.been.calledWith(PROPS2);
expect(proto.componentWillReceiveProps).to.have.been.calledWithMatch(
PROPS2
);
expect(proto.render).to.have.been.calledWithMatch(PROPS2);
});
});
});

0 comments on commit 46d0e7a

Please sign in to comment.