Addon used to experiment with React Hooks
style APIs in Ember apps viaexisting public APIs.
ember install hooks-component
This addon provide 2 DIFFERENT - API's
The hooks-component
API supports public React HooksAPI
useEffect
-> just like in React APIuseState
-> just like in React APIuseLayoutEffect
-> just like in React APIgetService
-> getService(serviceName)
-> service lookup hookgetController
-> getController(serviceName)
-> controller lookup hookgetRoute
-> getRoute(routeName)
-> route lookup hookgetStore
-> store service lookupgetOwner
-> getOwner()
-> equals getOwner(this)
in Ember.import { reactComponent, useEffect, useState } from "hooks-component";
function ConferenceSpeakersReact() {
const [ speakers ] = useState(['Tom', 'Yehuda', 'Ed']);
const [ current, updateCurrent ] = useState(0);
useEffect(() => {
console.log('dummy effect');
});
const next = () => {
let nextSpeaker = current + 1;
updateCurrent(nextSpeaker);
}
return {
currentlySpeaking: speakers[current],
moreSpeakers: (speakers.length - 1) > current,
current,
next, speakers
}
}
export default reactComponent(ConferenceSpeakersReact);
getContextId
-> getContextId()
-> get current instance context id (same between rerenders)getRerender
-> return binded to current instance update
functionaddBeforeCallTask
-> execute some callback before component update
addBeforeDestroyTask
-> execute some callback before any component destroy
// utils/custom-hook.js
import { getContextId, getRerender, addBeforeCallTask, addBeforeDestroyTask } from "hooks-component";
const DUMMY_STORE = {};
var CALL_COUNTER = 0;
addBeforeCallTask(()=>{
CALL_COUNTER = 0;
});
addBeforeDestroyTask(()=>{
const uid = getContextId();
if (uid in DUMMY_STORE) {
delete DUMMY_STORE[uid];
}
});
export function myCustomHook(componentStoreDefaultValue = {}) {
const uid = getContextId(); // current component instance ID
const hookCallId = CALL_COUNTER; // how many times hook called during rendering
if (!(uid in DUMMY_STORE)) {
DUMMY_STORE[uid] = {}; // init store for component instance;
}
if (!(hookCallId in DUMMY_STORE[uid])) {
// init store for exact call number inside component isntance;
DUMMY_STORE[uid][hookCallId] = componentStoreDefaultValue;
}
// get current instance + callNumber state
let state = DUMMY_STORE[uid][hookCallId];
// get rerender function (must be inside hook)
let rerender = getRerender();
// increment hook call counter
CALL_COUNTER++;
// return current state for exact component and callNumber and update state function
return [ state, function(newState) {
Object.assign(state, newState);
// rerender will invoke component rerender
rerender();
}
}
import { reactComponent } from "hooks-component";
import myCustomHook from "utils/custom-hook";
function ConferenceSpeakersReact() {
const [ state , patchState ] = myCustomHook({ keys: 1 });
const [ fish, patchFish ] = myCustomHook({ salmon: 1 });
const { keys } = state;
const { salmon } = fish;
const next = () => {
patchState({
keys: keys + 1
})
}
const addSalmon = () => {
patchFish({
salmon: salmon + 1
})
}
return { keys, next, salmon }
}
export default reactComponent(ConferenceSpeakersReact);
The hooks-component
API supports part of React hooks API, including:
updateContext - just like setProperties;
useEffect - do some calculation after dependent keys changed
extract - just like getWithDefault for component arguments
useEffect
- inside component function
context support: function, tracked property paths in array-like style ['foo.length', 'foo', 'foo.firstObject']
;
All effects called during first render, on rerender effects called only if "tracked" property changed.
// app/components/conference-speakers.js (.ts would also work)
import hookedComponent from "hooks-component";
function ConferenceSpeakers(attrs = {}) {
const { updateContext, useEffect, extract } = this;
useEffect(({current, speakers}) => {
updateContext({
currentlySpeaking: speakers[current],
moreSpeakers: (speakers.length - 1) > current
})
}, ['current'] );
const next = (current) => {
current++;
updateContext({
current
});
}
return extract(attrs, {
next,
current: 0,
speakers: ['Tom', 'Yehuda', 'Ed']
});
}
export default hookedComponent(ConferenceSpeakers);
function shouldRecomputeEffect(oldObject: object, newObject: object): boolean;
type Tracker = string | object | shouldRecomputeEffect;
type cleanupComputedEffect = undefined | Function;
function computeEffect(newContext: any): cleanupComputedEffect;
function useEffect(computeEffect, trakedItems?: Tracker | Tracker[] , useTrackersOnFirstRender?: boolean = false)
Current hookedComponents implementation logic:
component function
only once, in component creation time.component function
accept named params (args
) as first argument, and return context object
.updateContext
method invoke existing effects and then, do setProperties(currentContext, updatedProps)
.args
updated, it invokes updateContext
method with updated args
.useEffect
method adds "after updateContext
and before setProperties
callbacks with updatedProps
object as argument";useEffect
call return function, it will be called before this effect call next time.updateContext
inside useEffect
don't reinvoke effects, just patching updatedProps
with new data.git clone <repository-url>
cd hooks-component
yarn install
yarn lint:js
yarn lint:js --fix
ember test
– Runs the test suite on the current Ember versionember test --server
– Runs the test suite in "watch mode"ember try:each
– Runs the test suite against multiple Ember versionsember serve
For more information on using ember-cli, visit https://ember-cli.com/.
This project is licensed under the MIT License.
问题内容: 我有一个要在组件扫描时排除的类。我正在使用下面的代码来做到这一点,但这似乎没有用,尽管一切似乎都正确 实际上,我想在我的其余api逻辑中使用实现“ Service”接口的“ ServiceImpl”类,并在进行api的集成测试时希望排除这种实现并加载模拟的实现。但这似乎没有发生,即使使用上面的内容我也收到以下错误 我花了太多时间在此上,但没有任何效果。 任何帮助表示赞赏。 问题答案:
问题内容: 我正在使用Spring 3.1,并使用和属性引导应用程序。 实际的开始是 该配置类带有注释 而且效果很好。但是,我想更详细地说明我扫描的软件包,所以我尝试了。 但是,此操作失败,并显示错误消息,提示我找不到使用注释指定的组件。 做我追求的正确方法是什么? 谢谢 问题答案: @ComponentScan使用字符串数组,如下所示: 当您仅在一个字符串中提供多个包名称时,Spring会将其解
问题内容: 我有一个要从特定对象中排除的组件: 否则,它似乎与我项目中的其他班级发生冲突。我不完全理解碰撞,但是如果注释掉注释,事情就会像我希望的那样工作。但是其他依赖于此库的项目希望此类由Spring管理,因此我只想在我的项目中跳过它。 我尝试使用: 但它似乎不起作用。如果尝试使用,则会收到一个奇怪的错误,提示你无法加载一些看似随机的类: 原因:java.io.FileNotFoundExcep
问题内容: 我想在Spring中从基于XML的配置切换为基于Java的配置。现在,我们的应用程序上下文中具有以下内容: 但是如果我写这样的话… …它将从这两个软件包中排除服务。我有一种强烈的感觉,我正在尴尬地忽略一些琐碎的事情,但是找不到解决方案来将过滤器的范围限制为。 问题答案: 你只需要为所需的两个注释创建两个类。 因此,例如,你的包装将有一个类: 然后是你的包裹的二等舱: 然后在实例化Spr
问题内容: 我知道它的菜鸟问题,我真的在询问之前四处搜寻。但是我想知道的事情并没有确切的答案。我们如何不使用目标C将字符串拆分为数组?例如: 我知道它不起作用,但是我正在寻找那样的东西。我想用“”分割字符串(或其他字符/字符串) 想法:对我来说可能很好,扩展了字符串类。但是我不知道我该怎么做。 编辑:忘记导入基础。如果我导入基础,它将起作用。但是与扩展String类有什么关系吗?谢谢 问题答案:
我正在使用令人敬畏的“样式化组件” 但我现在使用的是另一个包,它将一个元素封装在其中,所以我不能将我的StyledComponents推到那里,因为我不想更改他的包。 我看到《魅力》有一个很好的把戏。StyledComponents支持这一点吗? 如果你想知道我为什么需要它,这里有一个例子:这是我正在使用的一个外部包: 所以你可以看到我需要传递一个json风格或类Name 所以魅力在这里会起作用,