Вы не можете выбрать более 25 тем Темы должны начинаться с буквы или цифры, могут содержать дефисы(-) и должны содержать не более 35 символов.
 
 
 

73 строки
2.2 KiB

  1. import { enqueueRender } from './component';
  2. export let i = 0;
  3. export function createContext(defaultValue, contextId) {
  4. contextId = '__cC' + i++;
  5. const context = {
  6. _id: contextId,
  7. _defaultValue: defaultValue,
  8. /** @type {import('./internal').FunctionComponent} */
  9. Consumer(props, contextValue) {
  10. // return props.children(
  11. // context[contextId] ? context[contextId].props.value : defaultValue
  12. // );
  13. return props.children(contextValue);
  14. },
  15. /** @type {import('./internal').FunctionComponent} */
  16. Provider(props) {
  17. if (!this.getChildContext) {
  18. /** @type {import('./internal').Component[]} */
  19. let subs = [];
  20. let ctx = {};
  21. ctx[contextId] = this;
  22. this.getChildContext = () => ctx;
  23. this.shouldComponentUpdate = function(_props) {
  24. if (this.props.value !== _props.value) {
  25. // I think the forced value propagation here was only needed when `options.debounceRendering` was being bypassed:
  26. // https://github.com/preactjs/preact/commit/4d339fb803bea09e9f198abf38ca1bf8ea4b7771#diff-54682ce380935a717e41b8bfc54737f6R358
  27. // In those cases though, even with the value corrected, we're double-rendering all nodes.
  28. // It might be better to just tell folks not to use force-sync mode.
  29. // Currently, using `useContext()` in a class component will overwrite its `this.context` value.
  30. // subs.some(c => {
  31. // c.context = _props.value;
  32. // enqueueRender(c);
  33. // });
  34. // subs.some(c => {
  35. // c.context[contextId] = _props.value;
  36. // enqueueRender(c);
  37. // });
  38. subs.some(c => {
  39. c._force = true;
  40. enqueueRender(c);
  41. });
  42. }
  43. };
  44. this.sub = c => {
  45. subs.push(c);
  46. let old = c.componentWillUnmount;
  47. c.componentWillUnmount = () => {
  48. subs.splice(subs.indexOf(c), 1);
  49. if (old) old.call(c);
  50. };
  51. };
  52. }
  53. return props.children;
  54. }
  55. };
  56. // Devtools needs access to the context object when it
  57. // encounters a Provider. This is necessary to support
  58. // setting `displayName` on the context object instead
  59. // of on the component itself. See:
  60. // https://reactjs.org/docs/context.html#contextdisplayname
  61. return (context.Provider._contextRef = context.Consumer.contextType = context);
  62. }